NOI2015软件包管理器 树剖线段树
题目:
一棵树,兹磁
1.查询根到一个点的染色点数并全染好
2.查询子树内染色点数并把颜色洗掉
树剖裸题,丝毫不虚(为什么我考试的时候碰不到这种好题呢)好像20min写完搞定
1 #include <bits/stdc++.h> 2 #define mid (l+r>>1) 3 using namespace std; 4 int TIME,n,m,t;char ch; 5 int size[200001],fir[200001],nex[200001],top[200001]; 6 int pos[200001],en[200001],fa[200001]; 7 int fz[800001],sum[800001]; 8 int dfs(int now) 9 { 10 size[now]=1; 11 for(int i=fir[now];i;i=nex[i]) 12 size[now]+=dfs(i); 13 return size[now]; 14 } 15 void pou(int now,int tp) 16 { 17 top[now]=tp;pos[now]=++TIME; 18 int best=fir[now]; 19 for(int i=fir[now];i;i=nex[i]) 20 if(size[i]>size[best]) best=i; 21 if(best) 22 pou(best,tp); 23 for(int i=fir[now];i;i=nex[i]) 24 if(i!=best) pou(i,i); 25 en[now]=TIME; 26 } 27 void down(int now,int l,int r) 28 { 29 if(fz[now]>-1) 30 { 31 fz[now<<1]=fz[now<<1|1]=fz[now]; 32 sum[now<<1]=(mid-l+1)*fz[now]; 33 sum[now<<1|1]=(r-mid)*fz[now]; 34 fz[now]=-1; 35 } 36 } 37 int que(int now,int l,int r,int x,int y) 38 { 39 if(l==x && r==y) 40 return sum[now]; 41 down(now,l,r); 42 int ret=0; 43 if(x<=mid) 44 ret+=que(now<<1,l,mid,x,min(mid,y)); 45 if(y>mid) 46 ret+=que(now<<1|1,mid+1,r,max(mid+1,x),y); 47 return ret; 48 } 49 void change(int now,int l,int r,int x,int y,int z) 50 { 51 if(l==x && r==y) 52 { 53 sum[now]=z*(r-l+1); 54 fz[now]=z; 55 return; 56 } 57 down(now,l,r); 58 if(x<=mid) 59 change(now<<1,l,mid,x,min(mid,y),z); 60 if(y>mid) 61 change(now<<1|1,mid+1,r,max(mid+1,x),y,z); 62 sum[now]=sum[now<<1]+sum[now<<1|1]; 63 } 64 int main() 65 { 66 scanf("%d",&n); 67 for(int i=2;i<=n;i++) 68 scanf("%d",&fa[i]),++fa[i],nex[i]=fir[fa[i]],fir[fa[i]]=i; 69 dfs(1);pou(1,1); 70 scanf("%d",&m); 71 for(int i=1;i<=m;i++) 72 { 73 for(ch=getchar();!isalpha(ch);ch=getchar()); 74 if(ch=='i') 75 { 76 for(int i=1;i<=6;i++) 77 getchar(); 78 scanf("%d",&t);++t; 79 int ret=0; 80 for(;t;t=fa[top[t]]) 81 ret+=pos[t]-pos[top[t]]+1-que(1,1,n,pos[top[t]],pos[t]), 82 change(1,1,n,pos[top[t]],pos[t],1); 83 printf("%d\n",ret); 84 } 85 if(ch=='u') 86 { 87 for(int i=1;i<=8;i++) 88 getchar(); 89 scanf("%d",&t);++t; 90 printf("%d\n",que(1,1,n,pos[t],en[t])); 91 change(1,1,n,pos[t],en[t],0); 92 } 93 } 94 return 0; 95 }