1. 程式人生 > >[NOI2015,LuoguP2146]軟件包管理器------樹剖

[NOI2015,LuoguP2146]軟件包管理器------樹剖

inline can swa %s noi digi main 軟件包管理 ans

***題目鏈接戳我***

  又是在樹上瞎搞滴題目....

  我們如果以安裝的軟件為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 }

[NOI2015,LuoguP2146]軟件包管理器------樹剖