Luogu P5658 括号树|搜索+递推

Posted fmj123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P5658 括号树|搜索+递推相关的知识,希望对你有一定的参考价值。

CSP2019 S组D1T2

题目链接

#include<bits/stdc++.h>
using namespace std;
int cc,to[600000],net[600000],fr[600000],fa[600000],zhan[600000],t,n,nt[600000];
long long s[600000];
char ch[600000];string st;bool vis[600000];
void addedge(int u,int v)
{
    cc++;
    to[cc]=v;net[cc]=fr[u];fr[u]=cc;
}
void dfs1(int x)
{
    if (ch[x]=='(') 
    {
        zhan[++t]=x;
    }
    else
    {
        nt[x]=t;
        while (vis[zhan[nt[x]]]&&nt[x])
        {
            nt[x]--;
        }
        if (nt[x])
        {
            vis[zhan[nt[x]]]=true;
            s[x]=s[x]+1+s[fa[zhan[nt[x]]]];
        }
    }
    for (int i=fr[x];i;i=net[i])
    {
        dfs1(to[i]);
    }
    if (ch[x]=='(')
         t--;
    else vis[zhan[nt[x]]]=false;
}
void dfs2(int x)
{
    for (int i=fr[x];i;i=net[i])
    {
        s[to[i]]+=s[x];
        dfs2(to[i]);
    }
}
int main()
{
//  freopen("brackets.in","r",stdin);
//  freopen("brackets.out","w",stdout);
    cin>>n;
    cin>>st;
    for (int i=1;i<=n;i++)
    {
        ch[i]=st[i-1];
    }
    bool lian=true;
    for (int i=2;i<=n;i++)
    {
        cin>>fa[i];
        if (fa[i]!=i-1) lian=false;
        addedge(fa[i],i);
    }   
/*  if (lian)
    {
        for (int i=1;i<=n;i++)
        {
            if (ch[i]=='(') 
            {
                zhan[++t]=i;
            }
            else 
            {
                if (!t) continue; 
                s[i]=1+s[fa[zhan[t]]];
                t--;
            }
        }
        for (int i=1;i<=n;i++)
        {
            s[i]+=s[i-1];
        }
    }
    else*/
    {
        dfs1(1);
        dfs2(1);
    }
    long long ans=s[1];
    for (int i=2;i<=n;i++)
    {
        ans^=s[i]*i;
    }
    cout<<ans<<endl;
    return 0;
}

以上是关于Luogu P5658 括号树|搜索+递推的主要内容,如果未能解决你的问题,请参考以下文章

P5658 括号树

递推与递归原理解释

Luogu_P2536 [AHOI2005]病毒检测 trie树+dfs

斐波那契数列递归树

Luogu P3369 普通平衡树 | 二叉搜索树(然而被卡了一个点)

Luogu5307 [COCI2019] Mobitel 数论分块递推