卸载:把子树清空;
安装:把自己到$1$的链改为$1$
#include<cstdio> #include<iostream> #include<cstring> #define R register int #define ls (tr<<1) #define rs (tr<<1|1) using namespace std; inline int g() { R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; } const int N=100010; int n,m,cnt,num; int vr[N<<1],nxt[N<<1],fir[N],sz[N],top[N],dfn[N],pre[N],d[N],son[N],sum[N<<2],tg[N<<2]; inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;} inline void dfs1(int u) { sz[u]=1; R mx=0; for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; if(!d[v]) { d[v]=d[u]+1; dfs1(v); sz[u]+=sz[v]; if(sz[v]>mx) son[u]=v,mx=sz[v]; } } } inline void dfs2(int u,int tp) { top[u]=tp; dfn[u]=++num; if(son[u]) dfs2(son[u],tp); for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; if(v!=pre[u]&&v!=son[u]) dfs2(v,v); } } inline void spread(int tr,int l,int r) { if(~tg[tr]) { R md=l+r>>1; tg[ls]=tg[tr],sum[ls]=(md-l+1)*tg[tr]; tg[rs]=tg[tr],sum[rs]=(r-md)*tg[tr]; tg[tr]=-1; } } inline void update(int tr,int l,int r,int LL,int RR,int d) { if(LL<=l&&r<=RR) {tg[tr]=d,sum[tr]=(r-l+1)*d; return ;} spread(tr,l,r); R md=l+r>>1; if(LL<=md) update(ls,l,md,LL,RR,d); if(RR>md) update(rs,md+1,r,LL,RR,d); sum[tr]=sum[ls]+sum[rs]; } inline void change(int u,int inc) { while(top[u]!=1) { update(1,1,n,dfn[top[u]],dfn[u],inc); u=pre[top[u]]; } update(1,1,n,1,dfn[u],inc); } signed main() { memset(tg,0xff,sizeof(tg)); n=g(); for(R i=2,u;i<=n;++i) u=g()+1,add(u,i),add(i,u),pre[i]=u; d[1]=1,dfs1(1); dfs2(1,1); m=g(); for(R i=1,x;i<=m;++i) { register char ch; while(!isalpha(ch=getchar())); R tmp=sum[1]; x=g()+1; if(ch=='i') change(x,1),printf("%d ",sum[1]-tmp); else if(ch=='u') { update(1,1,n,dfn[x],dfn[x]+sz[x]-1,0); printf("%d ",tmp-sum[1]); } } }
2019.07.03