裸的树链剖分。
对于安装 查询和维护到根路径
对于卸载 查询和维护子树信息
一开始线段树add[]标记要全赋值为-1
#include<algorithm>#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>#include<cmath>using namespace std; typedef long long LL; #define N 200010 int id;int fa[N],siz[N],top[N],son[N];int pos[N],r[N];LL sum[N<<2],add[N<<2]; struct Node{ int to,next;}e[N];int head[N];int cnt;int a;char s;int n,q;int read(){ int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f;}void link(int x,int y){ e[++cnt]=(Node){y,head[x]}; head[x]=cnt;} void dfs(int x){ siz[x]=1; for (int i=head[x],mx=0;i;i=e[i].next) if (e[i].to!=fa[x]) { fa[e[i].to]=x; dfs(e[i].to); siz[x]+=siz[e[i].to]; if (siz[e[i].to]>mx) mx=siz[e[i].to],son[x]=e[i].to; }} void dfs2(int x,int cha){ top[x]=cha; pos[x]=++id; if (son[x]) dfs2(son[x],cha); for (int i=head[x];i;i=e[i].next) if(e[i].to!=fa[x] && e[i].to!=son[x]) dfs2(e[i].to,e[i].to); r[x]=id;}void pushup(int now){ sum[now]=sum[now<<1]+sum[now<<1|1];}void pushdown(int nowl,int nowr,int now,int mid){ if (add[now]!=-1) { LL t=add[now]; add[now]=-1; add[now<<1]=t; add[now<<1|1]=t; sum[now<<1]=t*(mid-nowl+1); sum[now<<1|1]=t*(nowr-mid); }} void update(int nowl,int nowr,int now,int s,int t,LL d){ if (nowl>=s && nowr<=t) { add[now]=d; sum[now]=(nowr-nowl+1)*d; return ; } int mid=(nowl+nowr)>>1; pushdown(nowl,nowr,now,mid); if (s<=mid) update(nowl,mid,now<<1,s,t,d); if (t>mid) update(mid+1,nowr,now<<1|1,s,t,d); pushup(now);} int query(int nowl,int nowr,int now,int s,int t){ if (nowl>=s && nowr<=t) return sum[now]; int mid=(nowl+nowr)>>1; int ans=0; pushdown(nowl,nowr,now,mid); if (s<=mid) ans+=query(nowl,mid,now<<1,s,t); if (t>mid) ans+=query(mid+1,nowr,now<<1|1,s,t); return ans;}int work1(int x){ int ans,res=0; while (x) { ans=query(1,n,1,pos[top[x]],pos[x]); res+=pos[x]-pos[top[x]]+1-ans; update(1,n,1,pos[top[x]],pos[x],1); if (ans) break; x=fa[top[x]]; } return res;}int work2(int x) { int res; res=query(1,n,1,pos[x],r[x]); update(1,n,1,pos[x],r[x],0); return res; }int main(){ n=read(); for (int i=1;i<n;i++) { a=read(); link(a+1,i+1); } dfs(1); dfs2(1,1); memset(add,-1,sizeof(add)); q=read(); while (q--) { scanf("%c",&s); a=read(); if (s==‘i‘) printf("%d\n",work1(a+1)); else printf("%d\n",work2(a+1)); } return 0;}原文:http://www.cnblogs.com/yangjiyuan/p/5335077.html