bzoj4448 情报传递
离线+树上主席树,主席树维护时间标记
注意查询时如果c<0要把c赋为0;
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<string> 5 #include<cstring> 6 #include<cmath> 7 #define re(i,l,r) for(int i=(l);i<=(r);i++) 8 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 9 using namespace std; 10 template <typename Q> 11 void inin(Q &ret) 12 { 13 ret=0;int f=0;char ch=getchar(); 14 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 15 while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); 16 ret=f?-ret:ret; 17 } 18 const int xxx=200020; 19 int n,fa[xxx],w[xxx],head[xxx<<1],next[xxx<<1],zhi[xxx<<1],ed; 20 void add(int a,int b) 21 { 22 next[++ed]=head[a],head[a]=ed,zhi[ed]=b; 23 next[++ed]=head[b],head[b]=ed,zhi[ed]=a; 24 } 25 namespace pou 26 { 27 int top[xxx],shen[xxx],son[xxx]; 28 int dfs(int x) 29 { 30 int ret=1,temp,Max=0; 31 for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x]) 32 { 33 shen[zhi[i]]=shen[x]+1,fa[zhi[i]]=x; 34 temp=dfs(zhi[i]);ret+=temp; 35 if(Max<temp)Max=temp,son[x]=zhi[i]; 36 } 37 return ret; 38 } 39 void dfs(int x,int t) 40 { 41 if(!x)return ; 42 top[x]=t; 43 dfs(son[x],t); 44 for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x]&&zhi[i]!=son[x]) 45 dfs(zhi[i],zhi[i]); 46 } 47 int lca(int x,int y) 48 { 49 while(top[x]!=top[y]) 50 if(shen[top[x]]>shen[top[y]])x=fa[top[x]]; 51 else y=fa[top[y]]; 52 return shen[x]<shen[y]?x:y; 53 } 54 } 55 namespace pst 56 { 57 int root[xxx],sum[xxx<<4],ed,ch[xxx<<4][2]; 58 void update(int l,int r,int L,int &R,int x) 59 { 60 R=++ed;sum[R]=sum[L]+(x?1:0); 61 if(!x){ch[R][0]=ch[L][0],ch[R][1]=ch[L][1];return ;} 62 if(l==r)return ; 63 int mid=(l+r)>>1; 64 if(x<=mid)ch[R][1]=ch[L][1],update(l,mid,ch[L][0],ch[R][0],x); 65 else ch[R][0]=ch[L][0],update(mid+1,r,ch[L][1],ch[R][1],x); 66 } 67 void build(int x) 68 { 69 update(1,n,root[fa[x]],root[x],w[x]); 70 for(int i=head[x];i;i=next[i])if(zhi[i]!=fa[x]) 71 build(zhi[i]); 72 } 73 int query(int l,int r,int x,int c) 74 { 75 if(c==0)return 0; 76 if(l>=1&&r<=c)return sum[x]; 77 int mid=(l+r)>>1; 78 if(c<=mid)return query(l,mid,ch[x][0],c); 79 else return query(l,mid,ch[x][0],c)+query(mid+1,r,ch[x][1],c); 80 } 81 } 82 struct que 83 { 84 int x,y,c; 85 }sta[200020];int top; 86 int main() 87 { 88 inin(n); 89 re(i,1,n) 90 { 91 int x;inin(x); 92 if(x)add(i,x); 93 }pou::shen[1]=1; 94 pou::dfs(1); 95 pou::dfs(1,1); 96 int q;inin(q); 97 re(i,1,q) 98 { 99 int opt,x,y,c;inin(opt),inin(x); 100 if(opt==1)inin(y),inin(c),sta[++top]=(que){x,y,i-c-1}; 101 else w[x]=w[x]?w[x]:i; 102 } 103 pst::build(1); 104 re(i,1,top) 105 { 106 using namespace pou; 107 using namespace pst; 108 int temp=lca(sta[i].x,sta[i].y),x=sta[i].x,y=sta[i].y,c=sta[i].c;if(c<0)c=0; 109 printf("%d ",shen[sta[i].x]+shen[sta[i].y]-(shen[temp]<<1)+1); 110 printf("%d\n",query(1,n,root[x],c)+query(1,n,root[y],c)-2*query(1,n,root[fa[temp]],c)-(w[temp]<=c&&w[temp]>0)); 111 } 112 return 0; 113 }