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 } 

 

posted @ 2017-05-11 08:29  汪立超  阅读(196)  评论(0编辑  收藏  举报