主席树+树链剖分
对于每个时间点建一棵线段树
k=1时,找lca和查询在i-c-1时刻树上路径已被染色点数,此时新线段树等于前一时刻线段树
k=2时,直接插入更新新线段树即可
1 #include <bits/stdc++.h> 2 #define For(i,a,b) for(int i=a;i<=b;++i) 3 #define Dec(i,b,a) for(int i=b;i>=a;--i) 4 #define file() freopen("c://users/asus/desktop/v.txt","r",stdin) 5 #define inf 0x3f3f3f3f 6 using namespace std; 7 8 typedef unsigned long long ll; 9 inline ll qr(){ 10 ll x=0,f=1; char ch=getchar(); 11 while(!isdigit(ch)){if(ch=='-')f=-1; ch=getchar();} 12 while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48); ch=getchar();} 13 return x*f; 14 } 15 #define mid (l+r>>1) 16 const int N = 200010; 17 int sz[N],f[N][20],d[N],id[N],top[N],idx,son[N]; 18 int s[N*30],rt[N],ct,lc[N*30],rc[N*30]; 19 vector<int> g[N]; 20 int n,m,root; 21 void dfs1(int u) 22 { 23 sz[u]=1; 24 for(int i=1;f[u][i-1];++i) f[u][i]=f[f[u][i-1]][i-1]; 25 for(int i=0,v;i<g[u].size();++i) 26 { 27 if((v=g[u][i])==f[i][0]) continue; 28 f[v][0]=u; d[v]=d[u]+1; dfs1(v); sz[u]+=sz[v]; 29 if(sz[v]>sz[son[u]]) son[u]=v; 30 } 31 } 32 void dfs2(int u,int tp) 33 { 34 id[u]=++idx; top[u]=tp; 35 if(!son[u]) return; 36 dfs2(son[u],tp); 37 for(int i=0,v;i<g[u].size();++i) 38 if((v=g[u][i])!=f[u][0] && v!=son[u]) dfs2(v,v); 39 } 40 int lca(int x,int y) 41 { 42 if(d[x]<d[y]) swap(x,y); 43 Dec(i,18,0) if(d[f[x][i]]>=d[y]) x=f[x][i]; 44 if(x==y) return x; 45 Dec(i,18,0) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; 46 return f[x][0]; 47 } 48 void ins(int x,int &y,int l,int r,int p) 49 { 50 if(!y) y=++ct; 51 if(l==r) return (void)(s[y]=1); 52 if(p<=mid) rc[y]=rc[x],ins(lc[x],lc[y],l,mid,p); 53 else lc[y]=lc[x],ins(rc[x],rc[y],mid+1,r,p); 54 s[y]=s[lc[y]]+s[rc[y]]; 55 } 56 int qry(int x,int l,int r,int L,int R) 57 { 58 if(L<=l&&r<=R) return s[x]; 59 int t=0; 60 if(L<=mid) t+=qry(lc[x],l,mid,L,R); 61 if(mid<R) t+=qry(rc[x],mid+1,r,L,R); 62 return t; 63 } 64 int qrypath(int rt,int x,int y) 65 { 66 int t=0; 67 while(top[x]!=top[y]) 68 { 69 if(d[top[x]]<d[top[y]]) swap(x,y); 70 t+=qry(rt,1,n,id[top[x]],id[x]); 71 x=f[top[x]][0]; 72 } 73 if(d[x]>d[y]) swap(x,y); 74 return t+qry(rt,1,n,id[x],id[y]); 75 } 76 int main() 77 { 78 // file(); 79 n=qr(); int x; 80 For(i,1,n) if(x=qr()) g[x].push_back(i); 81 dfs1(1); dfs2(1,1); 82 m=qr(); int y,c,z,op,ans1=0,ans2=0; 83 For(i,1,m) 84 { 85 op=qr(); 86 if(op==2) ins(rt[i-1],rt[i],1,n,id[qr()]); 87 else 88 { 89 x=qr(),y=qr(),c=qr(); z=lca(x,y); 90 ans1=d[x]+d[y]-2*d[z]+1; 91 ans2=qrypath(rt[i-c-1],x,y); 92 printf("%d %d\n", ans1,ans2); 93 rt[i]=rt[i-1]; 94 } 95 } 96 return 0; 97 }