Luogu P5658 括号树|搜索+递推

时间:2020-01-19 00:30:43   收藏:0   阅读:94

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;
}
评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!