蒟蒻搞不懂思路为什么错~~~555555
查看原帖
蒟蒻搞不懂思路为什么错~~~555555
236980
王炸拆开打楼主2020/11/18 17:12

自认为非常对,思路受到了P3870开关的影响,问一下我的思路哪里错了

sum0记录未被安装的个数

sum1记录已安装的个数

然后RE了,就两个点AC,还有WA的点hhh

#include<iostream>
#include<cstdio>
#define Re register
using namespace std;
int cnt=0,dfn=0,suma=0;
int head[100010],id[100010],siz[100010],top[100010];
int son[100010],fa[100010],dep[100010];
int a[100010];
struct Node{
	int next,to;
}edge[200010];
struct NNN{
	int l,r,sum1,sum0,turn;
	#define l(x) t[x].l
	#define r(x) t[x].r
	#define sum0(x) t[x].sum0
	#define sum1(x) t[x].sum1
	#define turn(x) t[x].turn
}t[400010];
inline int read(){
	register int x=0,f=1;char ch=getchar();
	while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
	return x*f;
}
inline void adda(int u,int v){
	edge[++cnt].next=head[u];
	edge[cnt].to=v;
	head[u]=cnt;
}
void build(int l,int r,int p){
	l(p)=l;r(p)=r;
	if(l==r){sum0(p)=1;return;}
	Re int mid=(l+r)>>1;
	build(l,mid,p*2);
	build(mid+1,r,p*2+1);
	sum0(p)=sum0(p*2)+sum0(p*2+1);
}
void spread(int p){
	if(turn(p)==1){
		sum1(p*2)+=sum0(p*2);
		sum1(p*2+1)+=sum0(p*2+1);
		sum0(p*2)=0;sum0(p*2+1)=0;
		turn(p*2)=1;turn(p*2+1)=1;
		turn(p)=0;
	}
	if(turn(p)==2){
		sum0(p*2)+=sum1(p*2);
		sum0(p*2+1)+=sum1(p*2+1);
		sum1(p*2)=0;sum1(p*2+1)=0;
		turn(p*2)=2;turn(p*2+1)=2;
		turn(p)=0;
	}
}
void change_Install(int l,int r,int p){
	if(l<=l(p)&&r>=r(p)){
		sum1(p)+=sum0(p);
		suma+=sum0(p);
		sum0(p)=0;
		turn(p)=1;
		return;
	}
	spread(p);
	Re int mid=(l(p)+r(p))>>1;
	if(l<=mid) change_Install(l,r,p*2);
	if(r>mid) change_Install(l,r,p*2+1);
	sum1(p)=sum1(p*2)+sum1(p*2+1);
	sum0(p)=sum0(p*2)+sum0(p*2+1);
}
void change_Uninstall(int l,int r,int p){
	if(l<=l(p)&&r>=r(p)){
		sum0(p)+=sum1(p);
		suma+=sum1(p);
		sum1(p)=0;
		turn(p)=2;
		return;
	}
	spread(p);
	Re int mid=(l(p)+r(p))>>1;
	if(l<=mid) change_Uninstall(l,r,p*2);
	if(r>mid) change_Uninstall(l,r,p*2+1);
	sum1(p)=sum1(p*2)+sum1(p*2+1);
	sum0(p)=sum0(p*2)+sum0(p*2+1);
}
void dfs_1(int u,int fath,int step){
	dep[u]=step;fa[u]=fath;siz[u]=1;
	int maxx=-1;
	for(int i=head[u];i;i=edge[i].next){
		Re int x=edge[i].to;
		if(x==fath) continue;
		dfs_1(x,u,step+1);
		siz[u]+=siz[x];
		if(siz[x]>maxx) maxx=siz[x],son[u]=x;
	}
}
void dfs_2(int u,int topf){
	id[u]=++dfn;
	top[u]=topf;
	if(!son[u]) return;
	dfs_2(son[u],topf);
	for(int i=head[u];i;i=edge[i].next){
		Re int x=edge[i].to;
		if(x==fa[u]||x==son[u]) continue;
		dfs_2(x,x);
	}
}
inline int query(int x,bool bb){
	Re int y=0;Re int ans=0;
	if(!bb){
		suma=0;
		change_Uninstall(id[x],id[x]-1+siz[x],1);
		return suma;
	}
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		suma=0;
		change_Install(id[top[x]],id[x],1);
		ans+=suma;
		x=fa[top[x]];
	}
	if(dep[y]<dep[x]) swap(x,y);
	suma=0;
	change_Install(id[x],id[y],1);
	ans+=suma;
	return ans;
}
int main(){
	Re int n=read();
	n-=1;
	for(int i=1;i<=n;++i){
		Re int u=read();
		adda(u,i);
		fa[i]=u;
	}
	dfs_1(0,0,1);
	dfs_2(0,0);
	build(1,n,1);
	Re int q=read();
	while(q--){
		string s;
		cin>>s;
		Re int x=read();
		printf("%d\n",query(x,s[0]=='i'));
	}
	return 0;
}
2020/11/18 17:12
加载中...