bzoj4196 [Noi2015]软件包管理器 树链剖分+线段树

先把树剖分了(又是dfs1、dfs2),然后区间求和、区间覆盖即可

难得的1A好(shui)题

——写了那么多题,终于有一道是1A的了,加上上一次连续交了几遍A的程序,我的状态莫名好看啊233

总结:

1.开始用define简化代码

2.写的时候出现了手抖,还不够熟练

3.剖分基本上没有问题,线段树题目欠多

  1 #include <cstdio>
  2 #include <iostream>
  3 #define lson now*2
  4 #define rson now*2+1
  5 #define mid (l+r)/2
  6 using namespace std;
  7 int cnt=0,n,m;
  8 int flag[400001],t[400001];
  9 int fa[100001],size[100001],son[100001],bro[100001],b[100001],pos[100001],top[100001];
 10 int dfs1(int k)
 11 {
 12     size[k]=1;
 13     for(int i=son[k];i!=0;i=bro[i])
 14         size[k]+=dfs1(i);
 15     return size[k];
 16 }
 17 void dfs2(int k,int to)
 18 {
 19     b[++cnt]=k;
 20     top[k]=to;
 21     int max=son[k];
 22     pos[k]=cnt;
 23     for(int i=son[k];i!=0;i=bro[i])
 24         if(size[i]>size[max])
 25             max=i;
 26     if(max==0)
 27         return;
 28     dfs2(max,to);
 29     for(int i=son[k];i!=0;i=bro[i])
 30         if(i!=max)
 31             dfs2(i,i);
 32 }
 33 void down(int now,int l,int r)
 34 {
 35     if(flag[now]==1)
 36     {
 37         flag[lson]=1;
 38         flag[rson]=1;
 39         t[lson]=mid-l+1;
 40         t[rson]=r-mid;
 41         flag[now]=0;
 42     }
 43     if(flag[now]==2)
 44     {
 45         flag[lson]=2;
 46         flag[rson]=2;
 47         t[lson]=0;
 48         t[rson]=0;
 49         flag[now]=0;
 50     }
 51 }
 52 int que(int now,int l,int r,int x,int y)
 53 {
 54     if(l==x && r==y) return t[now];
 55     down(now,l,r);
 56     return ((x<=mid)?que(lson,l,mid,x,min(y,mid)):0)+((y>mid)?que(rson,mid+1,r,max(x,mid+1),y):0);    
 57 }
 58 void set_0(int now,int l,int r,int x,int y)
 59 {
 60     if(l==x && r==y) 
 61     {
 62         flag[now]=2;
 63         t[now]=0;
 64         return;
 65     }
 66     down(now,l,r);
 67     if(x<=mid)
 68         set_0(lson,l,mid,x,min(y,mid));
 69     if(y>mid)
 70         set_0(rson,mid+1,r,max(x,mid+1),y);
 71     t[now]=t[lson]+t[rson];
 72 }
 73 void set_1(int now,int l,int r,int x,int y)
 74 {
 75     if(l==x && r==y)     
 76     {
 77         flag[now]=1;
 78         t[now]=r-l+1;
 79         return;
 80     }
 81     down(now,l,r);
 82     if(x<=mid)
 83         set_1(lson,l,mid,x,min(y,mid));
 84     if(y>mid)
 85         set_1(rson,mid+1,r,max(x,mid+1),y);
 86     t[now]=t[lson]+t[rson];
 87 }
 88 int main()
 89 {
 90     scanf("%d",&n);
 91     for(int i=2;i<=n;i++)
 92     {
 93         scanf("%d",&fa[i]);
 94         fa[i]++;
 95         bro[i]=son[fa[i]];
 96         son[fa[i]]=i;
 97     }
 98     dfs1(1);
 99     dfs2(1,1);
100     scanf("%d",&m);
101     for(int i=1;i<=m;i++)
102     {
103         char ch=getchar();
104         while(ch!='i' && ch!='u')
105             ch=getchar();
106         bool b=ch=='i';
107         int x=0;
108         while(ch<'0' || ch>'9')
109             ch=getchar();
110         while(ch>='0' && ch<='9')
111         {
112             x=x*10+ch-'0';
113             ch=getchar();
114         }
115         x++;
116         if(b)
117         {
118             int sum=0;
119             for(int i=top[x];1;i=top[x])
120             {
121                 sum+=pos[x]-pos[i]+1-que(1,1,n,pos[i],pos[x]);
122                 set_1(1,1,n,pos[i],pos[x]);
123                 if(i==1)
124                     break;
125                 x=fa[i];
126             }
127             printf("%d\n",sum);
128         }
129         else
130         {
131             printf("%d\n",que(1,1,n,pos[x],pos[x]+size[x]-1));
132             set_0(1,1,n,pos[x],pos[x]+size[x]-1);
133         }
134     }
135     return 0;
136 }

 

posted @ 2016-07-20 15:43  汪立超  阅读(150)  评论(0编辑  收藏  举报