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 ;
}