10分(树剖)求助
查看原帖
10分(树剖)求助
507534
YBaggio楼主2022/3/27 09:29
#include<cstdio>
#include<iostream>
#include<cmath>
#define lc x<<1
#define rc x<<1|1
using namespace std;
const int maxn=2e5+10;
int dep[maxn],son[maxn],fa[maxn],dfn[maxn],top[maxn],tot,size[maxn];
int sum[maxn<<2],tag[maxn<<2];
int nex[maxn],to[maxn],head[maxn],cnt;
int n,m;
void dfs1(int x,int fat){
	size[x]=1;dep[x]=dep[fat]+1;fa[x]=fat;
	for(int i=head[x];i;i=nex[i]){
		if(to[i]==fat)continue;
		dfs1(to[i],x);
		size[x]+=size[to[i]];
		if(size[to[i]]>size[son[x]])son[x]=to[i];
	}
	return;
}	
void dfs2(int x,int stop){
	dfn[x]=++tot;top[x]=stop;
	if(!son[x])return;
	dfs2(son[x],stop);
	for(int i=head[x];i;i=nex[i])
		if(to[i]!=son[x]&&to[i]!=fa[x])dfs2(to[i],to[i]);
	return;
}	
void Add(int x,int l,int r,int v){tag[x]=v;sum[x]=v*(r-l+1);return;}
void add(int u,int v){to[++cnt]=v;nex[cnt]=head[u];head[u]=cnt;}
void pushdown(int x,int l,int r,int mid){
	if(!tag[x])return;
	Add(lc,l,mid,tag[x]);
	Add(rc,mid+1,r,tag[x]);
	tag[x]=0;	return;
}
void modify(int x,int l,int r,int s,int t,int v){
	if(s<=l&&r<=t)return Add(x,l,r,v);
	int mid=(l+r)/2; pushdown(x,l,r,mid);
	if(s<=mid)modify(lc,l,mid,s,t,v);
	if(mid<t)modify(rc,mid+1,r,s,t,v);
	sum[x]=(sum[lc]+sum[rc]);
	return;
}
void lianjia(int x,int y){
	while(top[x]!=top[y]){                
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		modify(1,1,n,dfn[top[x]],dfn[x],1);
		x=fa[top[x]];
	}	
	if(dep[x]>dep[y])swap(x,y);
	modify(1,1,n,dfn[x],dfn[y],1);
	return;
} 
int main(){
	scanf("%d",&n);
	for(int i=2;i<=n;i++){
		int x;scanf("%d",&x);
		add(x+1,i);
	}
	dfs1(1,0);dfs2(1,1);
	scanf("%d",&m);
	while(m--){
		int x,tmp=sum[1];char op[13];
		scanf("%s%d",op+1,&x);x++;
		if(op[1]=='i'){
		    lianjia(1,x);
			printf("%d\n",abs(tmp-sum[1])); 
		}else{
			modify(1,1,n,dfn[x],dfn[x]+size[x]-1,0);
			printf("%d\n",abs(tmp-sum[1]));
		}  
	}
	return 0;
}			
2022/3/27 09:29
加载中...