「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)

题目简介

咕咕咕。

分析

由题,显然,单个左括号无法构成贡献。

在一对括号中,右括号的贡献是 其对应的左括号前一个括号的贡献 \(+1\) 。

由图了解:
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)
「CSP-S2019」括号树 题解 (树的遍历,搜索,栈)

节点 \(x\) 的贡献和就是 \(k_x\)。

使用\(stack\)(栈) 来存储当先节点祖先的括号情况,如果栈顶元素能够与当前节点配对,则让栈顶元素出栈,否则让当前节点入栈。

为了避免子孙节点对栈的影响,也为了避免过多栈带来的程序空间不稳定,这里使用了 \(queue\)(队列)\(+BFS\)。

AC Code

#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
const int Maxn=5e5+5;
char str[Maxn];
struct Adjacency_List{
	int nxt;
	int t;
}tr[Maxn];
int h[Maxn];
int tot;
void add(int x,int y){
	tr[++tot].nxt=h[x];
	tr[tot].t=y;
	h[x]=tot;
}
struct node{
	int id;
	ll cnt;
	stack<int>st;
};
queue<node>q;
int fa[Maxn];
ll last[Maxn];
ll k[Maxn];
int main(){
	int n=read();
	scanf("%s",str+1);
	for(int i=2;i<=n;i++){
		int x=read();
		add(x,i);
		fa[i]=x;
	}
	node fir;
	fir.id=1;
	fir.cnt=0;
	fir.st.push(1);
	q.push(fir);
	while(!q.empty()){
		node tmp=q.front();
		q.pop();
//		cout<<' '<<tmp.id;
//		if(!tmp.st.empty())cout<<' '<<tmp.st.top()<<' '<<str[tmp.st.top()];
//		cout<<'\n'<<"  ";
		for(int i=h[tmp.id];i;i=tr[i].nxt){
			node t=tmp;
			t.id=tr[i].t;
//			cout<<t.id<<' ';
			if(str[t.id]==')'&&!t.st.empty()&&str[t.st.top()]=='('){
//				cout<<"\'"<<t.st.top()<<' '<<fa[t.st.top()]<<' ';
				last[t.id]=last[fa[t.st.top()]]+1;
				t.cnt+=last[t.id];
//				cout<<t.cnt<<' '<<k[t.id]<<' ';
//				cout<<last[fa[t.st.top()]]<<"\' ";
				t.st.pop();
			}else
				t.st.push(t.id);
			k[t.id]=t.cnt;
			q.push(t);
		}
//		cout<<'\n';
	}
	ll cnt=0;
//	for(int i=1;i<=n;i++)
//		cout<<k[i]<<' ';
//	cout<<'\n';
	for(int i=1;i<=n;i++)
		cnt^=1ll*i*k[i];
	printf("%lld\n",cnt);
	return 0;
} 

$$-----END-----$$

上一篇:python编程:turtle函数库笔记


下一篇:Clip Studio Paint(优动漫)如何提取线稿?