【bzoj4196】[Noi2015]软件包管理器

裸的树链剖分。

对于安装 查询和维护到根路径

对于卸载 查询和维护子树信息

 

一开始线段树add[]标记要全赋值为-1

  1  
  2 
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstdlib>
  6 #include<cstring>
  7 #include<cstdio>
  8 #include<cmath>
  9 using namespace std;
 10   
 11 typedef long long LL;
 12   
 13 #define N 200010
 14   
 15 int id;
 16 int fa[N],siz[N],top[N],son[N];
 17 int pos[N],r[N];
 18 LL sum[N<<2],add[N<<2];
 19   
 20 struct Node
 21 {
 22     int to,next;
 23 }e[N];
 24 int head[N];
 25 int cnt;
 26  
 27 int a;
 28  
 29 char s;
 30  
 31 int n,q;
 32  
 33 int read()
 34 {
 35     int x=0,f=1;char ch=getchar();
 36     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 37     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
 38     return x*f;
 39 }
 40  
 41 void link(int x,int y)
 42 {
 43     e[++cnt]=(Node){y,head[x]};
 44     head[x]=cnt;
 45 }
 46   
 47 void dfs(int x)
 48 {
 49     siz[x]=1;
 50     for (int i=head[x],mx=0;i;i=e[i].next)
 51         if (e[i].to!=fa[x])
 52         {
 53             fa[e[i].to]=x;
 54             dfs(e[i].to);
 55             siz[x]+=siz[e[i].to];
 56             if (siz[e[i].to]>mx)
 57                 mx=siz[e[i].to],son[x]=e[i].to;
 58         }
 59 }
 60   
 61 void dfs2(int x,int cha)
 62 {
 63     top[x]=cha;
 64     pos[x]=++id;
 65     if (son[x])
 66         dfs2(son[x],cha);
 67     for (int i=head[x];i;i=e[i].next)
 68         if(e[i].to!=fa[x] && e[i].to!=son[x])
 69             dfs2(e[i].to,e[i].to);
 70     r[x]=id;
 71 }
 72  
 73 void pushup(int now)
 74 {
 75     sum[now]=sum[now<<1]+sum[now<<1|1];
 76 }
 77  
 78 void pushdown(int nowl,int nowr,int now,int mid)
 79 {
 80     if (add[now]!=-1)
 81     {
 82         LL t=add[now];
 83         add[now]=-1;
 84         add[now<<1]=t;
 85         add[now<<1|1]=t;
 86         sum[now<<1]=t*(mid-nowl+1);
 87         sum[now<<1|1]=t*(nowr-mid);
 88     }
 89 }
 90   
 91 void update(int nowl,int nowr,int now,int s,int t,LL d)
 92 {
 93     if (nowl>=s && nowr<=t)
 94     {
 95         add[now]=d;
 96         sum[now]=(nowr-nowl+1)*d;
 97         return ;
 98     }
 99     int mid=(nowl+nowr)>>1;
100     pushdown(nowl,nowr,now,mid);
101     if (s<=mid)
102         update(nowl,mid,now<<1,s,t,d);
103     if (t>mid)
104         update(mid+1,nowr,now<<1|1,s,t,d);
105     pushup(now);
106 }
107   
108 int query(int nowl,int nowr,int now,int s,int t)
109 {
110     if (nowl>=s && nowr<=t)
111         return sum[now];
112     int mid=(nowl+nowr)>>1;
113     int ans=0;
114     pushdown(nowl,nowr,now,mid);
115     if (s<=mid)
116         ans+=query(nowl,mid,now<<1,s,t);
117     if (t>mid)
118         ans+=query(mid+1,nowr,now<<1|1,s,t);
119     return ans;
120 }
121  
122 int work1(int x)
123 {
124     int ans,res=0;
125     while (x)
126     {
127         ans=query(1,n,1,pos[top[x]],pos[x]);
128         res+=pos[x]-pos[top[x]]+1-ans; 
129         update(1,n,1,pos[top[x]],pos[x],1); 
130         if (ans)
131             break;
132         x=fa[top[x]];
133     }
134     return res;
135 }
136  
137 int work2(int x) 
138 { 
139     int res;
140     res=query(1,n,1,pos[x],r[x]); 
141     update(1,n,1,pos[x],r[x],0); 
142     return res; 
143 }
144  
145 int main()
146 {  
147      n=read();
148     for (int i=1;i<n;i++)
149     {
150         a=read();
151         link(a+1,i+1);
152     }
153     dfs(1);
154     dfs2(1,1);
155     memset(add,-1,sizeof(add));
156     q=read();
157     while (q--)
158     {
159         scanf("%c",&s);
160         a=read();
161         if (s=='i')
162             printf("%d\n",work1(a+1));
163         else
164             printf("%d\n",work2(a+1));
165     }
166     return 0;
167 }

 

posted @ 2016-03-29 22:18  Yangjiyuan  阅读(158)  评论(0编辑  收藏  举报