我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间
那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$
这个只要用主席树上树就可以解决了,顺便用树剖求一下LCA
1 //minamoto 2 #include<bits/stdc++.h> 3 using namespace std; 4 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 5 char buf[1<<21],*p1=buf,*p2=buf; 6 inline int read(){ 7 #define num ch-'0' 8 char ch;bool flag=0;int res; 9 while(!isdigit(ch=getc())) 10 (ch=='-')&&(flag=true); 11 for(res=num;isdigit(ch=getc());res=res*10+num); 12 (flag)&&(res=-res); 13 #undef num 14 return res; 15 } 16 char sr[1<<21],z[20];int C=-1,Z; 17 inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;} 18 inline void print(int x,char ch){ 19 if(C>1<<20)Ot(); 20 while(z[++Z]=x%10+48,x/=10); 21 while(sr[++C]=z[Z],--Z);sr[++C]=ch; 22 } 23 const int N=3e5+5,M=N*32; 24 struct node{int u,v,c,id;}q[N]; 25 int head[N],Next[N],ver[N],tot; 26 inline void add(int u,int v){ 27 ver[++tot]=v,Next[tot]=head[u],head[u]=tot; 28 } 29 int L[M],R[M],sum[M],rt[N],cnt; 30 void update(int last,int &now,int l,int r,int x){ 31 sum[now=++cnt]=sum[last]+1; 32 if(l==r) return; 33 int mid=(l+r)>>1; 34 if(x<=mid) R[now]=R[last],update(L[last],L[now],l,mid,x); 35 else L[now]=L[last],update(R[last],R[now],mid+1,r,x); 36 } 37 int fa[N],dep[N],top[N],sz[N],son[N],val[N],root,n,m,k; 38 void dfs1(int u){ 39 sz[u]=1,dep[u]=dep[fa[u]]+1; 40 update(rt[fa[u]],rt[u],1,m,val[u]); 41 for(int i=head[u];i;i=Next[i]){ 42 int v=ver[i]; 43 dfs1(v),sz[u]+=sz[v]; 44 if(sz[son[u]]<sz[v]) son[u]=v; 45 } 46 } 47 void dfs2(int u,int t){ 48 top[u]=t; 49 if(son[u]){ 50 dfs2(son[u],t); 51 for(int i=head[u];i;i=Next[i]) 52 if(ver[i]!=son[u]) dfs2(ver[i],ver[i]); 53 } 54 } 55 inline int LCA(int u,int v){ 56 while(top[u]!=top[v]) 57 dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]]; 58 return dep[u]<dep[v]?u:v; 59 } 60 int query(int u,int v,int lca,int lca_fa,int l,int r,int x){ 61 if(r<=x) return sum[u]+sum[v]-sum[lca]-sum[lca_fa]; 62 if(l>x) return 0; 63 int mid=(l+r)>>1,res=0; 64 if(x>=l) res+=query(L[u],L[v],L[lca],L[lca_fa],l,mid,x); 65 if(x>mid) res+=query(R[u],R[v],R[lca],R[lca_fa],mid+1,r,x); 66 return res; 67 } 68 int main(){ 69 // freopen("testdata.in","r",stdin); 70 n=read(); 71 for(int i=1;i<=n;++i){fa[i]=read(),add(fa[i],i);if(fa[i]==0) root=i;} 72 m=read();for(int i=1;i<=n;++i) val[i]=m; 73 for(int i=1;i<=m;++i){ 74 int op=read(),p; 75 if(op&1) q[++k].u=read(),q[k].v=read(),q[k].c=read(),q[k].id=i; 76 else val[p=read()]=i; 77 } 78 dfs1(root),dfs2(root,root); 79 for(int i=1;i<=k;++i){ 80 int u=q[i].u,v=q[i].v,lca=LCA(u,v),lca_fa=fa[lca]; 81 print(dep[u]+dep[v]-2*dep[lca]+1,' '); 82 int t=q[i].id-q[i].c-1; 83 print(t>0?query(rt[u],rt[v],rt[lca],rt[lca_fa],1,m,t):0,' '); 84 } 85 Ot(); 86 return 0; 87 }