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 括号树|搜索+递推的主要内容,如果未能解决你的问题,请参考以下文章
Luogu_P2536 [AHOI2005]病毒检测 trie树+dfs