[NOI2015,LuoguP2146]软件包管理器------树剖

***题目链接戳我***

  又是在树上瞎搞滴题目....

  我们如果以安装的软件为1,未安装的软件为0,那么软件改变的数量即树上权值总和的数量,涉及到区间修改,区间查询,考虑树剖

  分析完毕,似乎没啥好说的了。。。树剖模板题(然鹅我是不会告诉你们我因为把int打成char查了好久好久代码滴...)   

  细节问题:为了便于处理把每个节点编号都加上1,避免一些不必要的错误

  P.S.打完才发现好像不用区间查询

  代码:

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<iostream>
 4 using namespace std;
 5 inline int read(){
 6     int ans=0,f=1;char chr=getchar();
 7     while(!isdigit(chr)){if(chr=='-')f=-1;chr=getchar();}
 8     while(isdigit(chr)) {ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
 9     return ans*f;
10 }const int M=200005;int n,m;
11 inline int abs(int x) {if(x<0) return -x;return x;}
12 int head[M],ver[M],nxt[M],tot,fa[M],dep[M],son[M],top[M],idx[M],sz[M],t,sum[M<<2],lz[M<<2];    
13 inline void add(int x,int y){ver[++tot]=y;nxt[tot]=head[x];head[x]=tot;}
14 void dfs1(int x){
15     dep[x]=dep[fa[x]]+1;sz[x]=1;
16     for(int i=head[x];i;i=nxt[i]){
17         if(ver[i]==fa[x]) continue;
18         fa[ver[i]]=x,dfs1(ver[i]);sz[x]+=sz[ver[i]];
19         if(sz[ver[i]]>sz[son[x]]) son[x]=ver[i];
20     }
21 }void dfs2(int x,int topf){
22     idx[x]=++t;top[x]=topf;
23     if(!son[x]) return;dfs2(son[x],topf);
24     for(int i=head[x];i;i=nxt[i])
25         if(!idx[ver[i]]) dfs2(ver[i],ver[i]);
26 }inline void Push_Up(int i){sum[i]=sum[i<<1]+sum[i<<1|1];}
27  inline void Push_Down(int i,int l,int r){
28      if(lz[i]==0) return;int mid=l+r>>1;
29      if(lz[i]==-1) sum[i<<1]=sum[i<<1|1]=0,lz[i<<1]=lz[i<<1|1]=-1;
30      else sum[i<<1]=mid-l+1,sum[i<<1|1]=r-mid,lz[i<<1]=lz[i<<1|1]=1;
31      lz[i]=0;return;
32 }void Update(int i,int l,int r,int ql,int qr,int x){
33     if(ql<=l&&r<=qr){
34         if(!x)lz[i]=-1,sum[i]=0;//lz==-1-->Update->0  lz==1 --> Update->1
35         else lz[i]=1,sum[i]=r-l+1;
36         return;
37     }int mid=l+r>>1;Push_Down(i,l,r);
38     if(mid>=ql) Update(i<<1,l,mid,ql,qr,x);
39     if(mid<qr)  Update(i<<1|1,mid+1,r,ql,qr,x);
40     Push_Up(i);
41 }void Change(int v,int x,int y){
42     while(top[x]!=top[y]){
43         if(dep[top[x]]<dep[top[y]]) swap(x,y);
44         Update(1,1,n,idx[top[x]],idx[x],v);
45         x=fa[top[x]];
46     }if(dep[x]>dep[y]) swap(x,y);Update(1,1,n,idx[x],idx[y],v);
47 }
48 int main(){
49 //    freopen("rjb.in","r",stdin);
50     n=read();
51     for(int i=2;i<=n;i++){int x=read();++x;add(x,i);add(i,x);}
52     dfs1(1),dfs2(1,1);
53     m=read();char opt[20];int x,bf;
54     while(m--){scanf("%s",opt);x=read();bf=sum[1];++x; 
55         if(opt[0]=='i'){
56             Change(1,x,1);
57             printf("%d\n",abs(sum[1]-bf));
58         }else{
59             Update(1,1,n,idx[x],idx[x]+sz[x]-1,0);
60             printf("%d\n",abs(sum[1]-bf));
61         }
62     }
63     return 0;
64 }

猜你喜欢

转载自www.cnblogs.com/zhenglw/p/10356806.html