CSP2019 括号树
Posted oierwyh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CSP2019 括号树相关的知识,希望对你有一定的参考价值。
Description:
给定括号树,每个节点都是 (
或 )
,定义节点的权值为根到该节点的简单路径所构成的括号序列中不同合法子串的个数(子串需要连续,子串所在的位置不同即为不同。)与节点编号的乘积,求所有节点权值的异或和。
Solution:
闻到一股深深的 stack
气息。
Code:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5+1;
int n;
char s[N];
int fa[N],st[N],top;
ll sum[N],ans[N];
ll fin;
struct edge
{
int nxt;
int to;
}e[N];
int h[N],cnt;
void add(int u,int v)
{
e[++cnt].nxt=h[u];
e[cnt].to=v;
h[u]=cnt;
}
void dfs(int u)
{
int flag=0;
if(s[u]==')')
{
if(!top) goto here;
flag=st[top];
--top;
sum[u]=sum[fa[flag]]+1;
}
else if(s[u]=='(')
{
st[++top]=u;
}
here:;
ans[u]=ans[fa[u]]+sum[u];
for(int i=h[u];i;i=e[i].nxt)
dfs(e[i].to);
if(flag) st[++top]=flag;
else if(top) --top;
}
signed main()
{
scanf("%d",&n);
scanf("%s",s+1);
for(int i=2;i<=n;++i)
{
scanf("%d",&fa[i]);
add(fa[i],i);
}
dfs(1);
for(int i=1;i<=n;++i)
{
fin^=ans[i]*ll(i);
}
printf("%lld",fin);
return 0;
}
以上是关于CSP2019 括号树的主要内容,如果未能解决你的问题,请参考以下文章