2021.08.09 P5658 括号树(树形结构)
[P5658 CSP-S2019] 括号树 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题意:
太长,在链接中。
分析及代码:
//从一条链开始思考,得出num[x]=num[fa[x]]+1,sum[x]=sum[fa[x]]+num[x]
//接下来思考是一棵树的情况:只是比一条链多了回溯
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int N=5e5+10;
#define ll long long
char ch[N];
int n,cnt,head[N],fa[N],top,stacki[N];
ll num[N],sum[N];
struct node{
int to,next;
}a[N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
void add(int u,int v){
++cnt;
a[cnt].to=v;
a[cnt].next=head[u];
head[u]=cnt;
}
void dfs(int x){
int flag=0;
if(ch[x]==')'){
if(top){
flag=stacki[top];
--top;
num[x]=num[fa[flag]]+1;
//如果最近的'('的前一个是')',如果')'已经被匹配即num[fa[flag]]!=0,num[x]=num[fa[falg]]+1;
//否则,num[x]=1
}
}else if(ch[x]=='(')stacki[++top]=x;
sum[x]=sum[fa[x]]+num[x];
for(int i=head[x];i;i=a[i].next){
int v=a[i].to;
dfs(v);
}
if(flag)stacki[++top]=flag;//flag!=0:char[x]==')',一定删除了stacki[top]上的相距最近的'('的位置信息,回溯给还原
else if(top)--top;//flag==0:char[x]=='(',一定压入了x,回溯给还原
}
int main(){
n=read();
scanf("%s",ch+1);
for(int i=2;i<=n;i++){
int x=read();
fa[i]=x;
add(x,i);
}
dfs(1);
ll ans=0;
for(int i=1;i<=n;i++)ans^=(1ll*i*sum[i]);
cout<<ans;
return 0;
}
posted on
浙公网安备 33010602011771号