1. 程式人生 > >[BZOJ] 4196 [Noi2015]軟體包管理器

[BZOJ] 4196 [Noi2015]軟體包管理器

安裝操作就是鏈上統計+更改,解除安裝操作就是子樹統計+更改,沒有比樹剖更合適的了。
陣列開小會莫名WA..qwq

#include<iostream>
#include<cstdio>

using namespace std;

const int MAXN=1000005;

int n,m;

#define ls (cur<<1)
#define rs ((cur<<1)+1)
#define mid ((l+r)>>1)
int sum[MAXN],lazy[MAXN];
void pushup(int cur){sum[cur]=sum[ls]+sum[rs];}
void
pushdown(int cur,int l,int r){ sum[ls]=(lazy[cur])*(mid-l+1); sum[rs]=(lazy[cur])*(r-mid); lazy[ls]=lazy[rs]=lazy[cur]; lazy[cur]=-1; } void build(int cur,int l,int r){ if(l==r){sum[cur]=0;return;} build(ls,l,mid);build(rs,mid+1,r); lazy[cur]=-1; pushup(cur); } void updata(int L,int
R,int cur,int l,int r,int w){ if(L<=l&&r<=R){sum[cur]=w*(r-l+1);lazy[cur]=w;return;} if(lazy[cur]!=-1) pushdown(cur,l,r); if(L<=mid) updata(L,R,ls,l,mid,w); if(mid <R) updata(L,R,rs,mid+1,r,w); pushup(cur); } int query(int L,int R,int cur,int l,int r){ if(L<=l&&r<=R) return
sum[cur]; if(lazy[cur]!=-1) pushdown(cur,l,r); int ret=0; if(L<=mid) ret+=query(L,R,ls,l,mid); if(mid <R) ret+=query(L,R,rs,mid+1,r); return ret; } int query0(int L,int R,int cur,int l,int r){ if(L<=l&&r<=R) return r-l+1-sum[cur]; if(lazy[cur]!=-1) pushdown(cur,l,r); int ret=0; if(L<=mid) ret+=query0(L,R,ls,l,mid); if(mid <R) ret+=query0(L,R,rs,mid+1,r); return ret; } struct Edge{ int next,to; }e[MAXN<<1]; int ecnt,head[MAXN]; inline void add(int x,int y){ e[++ecnt].to = y; e[ecnt].next = head[x]; head[x] = ecnt; } int dep[MAXN],fa[MAXN],hs[MAXN],siz[MAXN]; void dfs1(int cur,int pre){ fa[cur]=pre;dep[cur]=dep[pre]+1;siz[cur]=1; int mx=-1; for(int i=head[cur];i;i=e[i].next){ int v=e[i].to; if(v==pre) continue; dfs1(v,cur); siz[cur]+=siz[v]; if(siz[v]>mx) mx=siz[v],hs[cur]=v; } } int top[MAXN],id[MAXN],cnt; void dfs2(int cur,int tp){ id[cur]=++cnt;top[cur]=tp; if(hs[cur]) dfs2(hs[cur],tp); for(int i=head[cur];i;i=e[i].next){ int v=e[i].to; if(v==fa[cur]||v==hs[cur]) continue; dfs2(v,v); } } int query_link(int x,int y){ int ret=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); ret+=query0(id[top[x]],id[x],1,1,n); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); ret+=query0(id[x],id[y],1,1,n); return ret; } void updata_link(int x,int y,int w){ while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); updata(id[top[x]],id[x],1,1,n,w); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); updata(id[x],id[y],1,1,n,w); } int query_subtree(int x){ return query(id[x],id[x]+siz[x]-1,1,1,n); } void updata_subtree(int x,int w){ updata(id[x],id[x]+siz[x]-1,1,1,n,w); } int main(){ scanf("%d",&n); int x; for(int i=2;i<=n;i++) { scanf("%d",&x); x++; add(i,x);add(x,i); } dfs1(1,0); dfs2(1,1); build(1,1,n); scanf("%d",&m); char s[500]; for(int i=1;i<=m;i++){ scanf("%s%d",s,&x); x++; if(s[0]=='i'){ printf("%d\n",query_link(1,x)); updata_link(1,x,1); }else{ printf("%d\n",query_subtree(x)); updata_subtree(x,0); } } return 0; }