f[i]表示:以i结尾的合法序列的个数。
我们用栈来记录’(‘的位置,对于当前出现的一个’(’,我们将它放入栈中;对于当前出现的一个’)’,如果栈为空,则无贡献,如果栈不为空,则可得:f[i]+=f[fa[sta[top]]]。
因为f[i]表示以i结尾的合法序列的个数,所以最后需要将以i节点的若干个祖先节点为结尾的合法序列的个数,累加至f[i]中,即:f[i]+=f[fa[i]]。
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e5+5;
int n,top;
int fa[N],sta[N],f[N];
int ans;
char str[N];
int cnt,head[N];
struct edge{int next,to;}e[N];
inline void add(int u,int v)
{
cnt++;
e[cnt].next=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void dfs(int u)
{
int jay=0;
if (str[u]=='(') sta[++top]=u;
else if (top)
{
jay=sta[top];
f[u]=f[fa[sta[top]]]+1;
top--;
}
for (register int i=head[u]; i; i=e[i].next) dfs(e[i].to);
if (str[u]=='(') top--;
else if (jay)
{
sta[++top]=jay;
}
}
void dfs2(int u)
{
for (register int i=head[u]; i; i=e[i].next)
{
f[e[i].to]+=f[u];
dfs2(e[i].to);
}
}
signed main(){
scanf("%lld",&n);
scanf("%s",str+1);
for (register int i=2; i<=n; ++i)
{
scanf("%lld",&fa[i]);
add(fa[i],i);
}
dfs(1);
dfs2(1);
for (register int i=1; i<=n; ++i) ans^=i*f[i];
printf("%lld\n",ans);
return 0;
}