树剖并维护每一个软件包的安装状态,插入操作即询问该节点到根有多少个0并全部修改为1,删除操作即询问子树(树剖的序列也是dfs序)中有多少个1并全部修改为0,用线段树来维护即可。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 100005 4 #define L (k<<1) 5 #define R (L+1) 6 #define mid (l+r>>1) 7 struct ji{ 8 int nex,to; 9 }edge[N<<1]; 10 int E,n,m,x,fa[N],sz[N],ma[N],top[N],id[N],head[N],tag[N<<2],f[N<<2]; 11 char s[11]; 12 void add(int x,int y){ 13 edge[E].nex=head[x]; 14 edge[E].to=y; 15 head[x]=E++; 16 } 17 void dfs1(int k,int f){ 18 fa[k]=f; 19 sz[k]=1; 20 for(int i=head[k];i!=-1;i=edge[i].nex) 21 if (edge[i].to!=f){ 22 dfs1(edge[i].to,k); 23 sz[k]+=sz[edge[i].to]; 24 if ((!ma[k])||(sz[ma[k]]<sz[edge[i].to]))ma[k]=edge[i].to; 25 } 26 } 27 void dfs2(int k,int t){ 28 top[k]=t; 29 id[k]=++x; 30 if (ma[k])dfs2(ma[k],t); 31 for(int i=head[k];i!=-1;i=edge[i].nex) 32 if ((edge[i].to!=fa[k])&&(edge[i].to!=ma[k]))dfs2(edge[i].to,edge[i].to); 33 } 34 void bj(int k,int l,int r,int p){ 35 tag[k]=p; 36 f[k]=(p-1)*(r-l+1); 37 } 38 void down(int k,int l,int r){ 39 if (tag[k]){ 40 bj(L,l,mid,tag[k]); 41 bj(R,mid+1,r,tag[k]); 42 tag[k]=0; 43 } 44 } 45 int update(int k,int l,int r,int x,int y,int z){ 46 if ((l>y)||(x>r))return 0; 47 if ((x<=l)&&(r<=y)){ 48 int ans=z*(r-l+1)-(2*z-1)*f[k]; 49 bj(k,l,r,z+1); 50 return ans; 51 } 52 down(k,l,r); 53 int ans=update(L,l,mid,x,y,z)+update(R,mid+1,r,x,y,z); 54 f[k]=f[L]+f[R]; 55 return ans; 56 } 57 int calc(int k){ 58 int ans=0; 59 while (k){ 60 ans+=update(1,1,n,id[top[k]],id[k],1); 61 k=fa[top[k]]; 62 } 63 return ans; 64 } 65 int main(){ 66 scanf("%d",&n); 67 memset(head,-1,sizeof(head)); 68 for(int i=2;i<=n;i++){ 69 scanf("%d",&x); 70 add(i,x+1); 71 add(x+1,i); 72 } 73 x=0; 74 dfs1(1,0); 75 dfs2(1,1); 76 scanf("%d",&m); 77 for(int i=1;i<=m;i++){ 78 scanf("%s%d",s,&x); 79 x++; 80 if (s[0]=='i')printf("%d\n",calc(x)); 81 else printf("%d\n",update(1,1,n,id[x],id[x]+sz[x]-1,0)); 82 } 83 return 0; 84 }