1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
| #include < cstdio > #include < cstring > #include < algorithm > const int maxn=200005; int n,k=0,x,head[maxn],q,deep[maxn],father[maxn],size[maxn]; int tid[maxn],top[maxn],son[maxn],tidnum=0,pos[maxn];char s[15]; struct node { int to,next; } edge[maxn<<1]; struct Node { int left,right,flag,sum; } tree[maxn<<2]; void add(int u,int v) { edge[++k].to=v; edge[k].next=head[u]; head[u]=k; } int read() { int x=0;char ch=getchar(); while(ch<48||ch>57) ch=getchar(); while(ch>=48&&ch<=57) x=x*10+ch-48,ch=getchar(); return x; } void dfs1(int x,int fa,int depth) { size[x]=1;father[x]=fa;deep[x]=depth; for(int i=head[x];i;i=edge[i].next) { if(edge[i].to==fa) continue; dfs1(edge[i].to,x,depth+1); size[x]+=size[edge[i].to]; if(!son[x]||size[edge[i].to]>size[son[x]]) son[x]=edge[i].to; } } void dfs2(int x,int tp) { tid[x]=++tidnum;pos[tid[x]]=x;top[x]=tp; if(!son[x]) return;dfs2(son[x],tp); for(int i=head[x];i;i=edge[i].next) { if(edge[i].to!=son[x]&&edge[i].to!=father[x]) dfs2(edge[i].to,edge[i].to); } } void build(int id,int l,int r) { tree[id].left=l;tree[id].right=r; tree[id].sum=0;tree[id].flag=-1; if(l==r) return; int mid=(l+r)>>1; build(id<<1,l,mid);build(id<<1|1,mid+1,r); return; } void downdata(int id) { tree[id<<1].sum=(tree[id<<1].right-tree[id<<1].left+1)*tree[id].flag; tree[id<<1|1].sum=(tree[id<<1|1].right-tree[id<<1|1].left+1)*tree[id].flag; tree[id<<1].flag=tree[id<<1|1].flag=tree[id].flag; tree[id].flag=-1; } int get(int id,int l,int r) { if(tree[id].right<l||tree[id].left>r) return 0; if(tree[id].right<=r&&tree[id].left>=l) return tree[id].sum; if(tree[id].flag!=-1) downdata(id); return get(id<<1,l,r)+get(id<<1|1,l,r); } void update(int id,int l,int r,int val) { if(tree[id].right<l||tree[id].left>r) return; if(tree[id].right<=r&&tree[id].left>=l) { tree[id].sum=(tree[id].right-tree[id].left+1)*val; tree[id].flag=val; return; } if(tree[id].flag!=-1) downdata(id); update(id<<1,l,r,val);update(id<<1|1,l,r,val); tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum; return; } void change(int u,int v,int val) { while(top[u]!=top[v]) { if(deep[top[u]]<deep[top[v]]) std::swap(u,v); update(1,tid[top[u]],tid[u],val); u=father[top[u]]; } if(deep[u]>deep[v]) std::swap(u,v); update(1,tid[u],tid[v],val); return; } int main() { n=read(); for(int i=2;i<=n;i++) { x=read();x++; add(x,i); } dfs1(1,1,1);dfs2(1,1); q=read();build(1,1,tidnum); for(int i=1;i<=q;i++) { scanf("%s",s); x=read();x++; int t1=tree[1].sum; if(s[0]=='i') { change(1,x,1); int t2=tree[1].sum; printf("%d\n",abs(t2-t1)); } if(s[0]=='u') { update(1,tid[x],tid[x]+size[x]-1,0); int t2=tree[1].sum; printf("%d\n",abs(t1-t2)); } } return 0; }
|