hdu5709Claris Loves Painting主席树 奇妙的DFS序
先不考虑层数限制
一棵树上每个点有个颜色,问一棵子树的颜色数
感觉简单多了是吧
考虑每个点的贡献:自己到根的路径上的一个包含自己的连续段
观察最顶端的点的父亲:
它满足有了额外的同色孩子(咦)
这一条链上需要+1(@miaom)
如果差分,就是在这个点+1(@miaom),在最近的有同色孩子的父亲-1,求子树和
最近的有同色孩子的父亲?
根据直觉,它一定是dfs序上和这个点相邻的同色点和这个点的lca
没了
再加上层数限制
相当于一定要在一定的深度以内
所以开主席树保持可持久化(怎么不能离线啊,好烦啊)
1 #include <bits/stdc++.h> 2 #define LOG 19 3 #define mid (l+r>>1) 4 using namespace std; 5 int NODE,n,m,p,q,E,TIME,x,d; 6 int dep[200001],nex[500001],fir[200001],Fir[200001],Nex[500001]; 7 int fa[200001][20],to[500001];//,ne[200001]; 8 int tr[8000001],ls[8000001],rs[8000001]; 9 int c[200001],root[200001],start[200001],en[200001],pos[200001]; 10 void dfs(int now,int fat) 11 { 12 dep[now]=dep[fat]+1;start[now]=++TIME;pos[TIME]=now; 13 Nex[now]=Fir[dep[now]];Fir[dep[now]]=now; 14 fa[now][0]=fat; 15 for(int i=1;fa[now][i-1];i++) fa[now][i]=fa[fa[now][i-1]][i-1]; 16 for(int i=fir[now];i;i=nex[i]) 17 if(to[i]!=fat) 18 dfs(to[i],now); 19 en[now]=TIME; 20 } 21 int lca(int x,int y) 22 { 23 if(dep[x]<dep[y]) swap(x,y); 24 for(int delta=dep[x]-dep[y],i=0;delta;delta>>=1,++i) 25 if(delta&1) x=fa[x][i]; 26 for(int i=LOG;i>=0;i--) 27 if(fa[x][i]!=fa[y][i]) 28 x=fa[x][i],y=fa[y][i]; 29 return (x==y)?x:fa[x][0]; 30 } 31 int chan(int acc,int l,int r,int x,int y) 32 { 33 int now=++NODE; 34 if(l==r) 35 { 36 tr[now]=tr[acc]+y; 37 return now; 38 } 39 if(x<=mid) ls[now]=chan(ls[acc],l,mid,x,y),rs[now]=rs[acc]; 40 else rs[now]=chan(rs[acc],mid+1,r,x,y),ls[now]=ls[acc]; 41 tr[now]=tr[ls[now]]+tr[rs[now]]; 42 return now; 43 } 44 void add(int x,int y) 45 { 46 to[++E]=y;nex[E]=fir[x];fir[x]=E; 47 } 48 int que(int now,int l,int r,int x,int y) 49 { 50 if(l==x && r==y) 51 return tr[now]; 52 int ret=0; 53 if(x<=mid) 54 ret+=que(ls[now],l,mid,x,min(y,mid)); 55 if(y>mid) 56 ret+=que(rs[now],mid+1,r,max(mid+1,x),y); 57 return ret; 58 } 59 set<pair<int,int> > se; 60 int main() 61 { 62 int T; 63 for(scanf("%d",&T);T;T--) 64 { 65 scanf("%d%d",&n,&m);E=0;TIME=0;NODE=0; 66 se.clear(); 67 for(int i=1;i<=n;i++) 68 scanf("%d",&c[i]); 69 for(int i=1;i<=n;i++) 70 fir[i]=0,Fir[i]=0; 71 for(int i=1;i<=n;i++) 72 for(int j=0;j<=19;j++) 73 fa[i][j]=0; 74 for(int i=1;i<n;i++) 75 scanf("%d",&q),add(q,i+1); 76 dfs(1,0);root[1]=1;tr[1]=0;ls[1]=0;rs[1]=0; 77 int MD=0; 78 for(int i=1;i<=n;root[i+1]=root[i],i++) 79 for(int j=Fir[i];j;j=Nex[j]) 80 { 81 int t=0; 82 pair <int,int> tem=*se.lower_bound(make_pair(c[j],start[j])); 83 int tem1=tem.first; 84 int Tem1=tem.second; 85 if(tem1==c[j]) t=lca(pos[Tem1],j); 86 if(se.lower_bound(make_pair(c[j],start[j]))!=se.begin()) 87 { 88 tem=*(--se.lower_bound(make_pair(c[j],start[j]))); 89 int tem2=tem.first; 90 int Tem2=tem.second; 91 if(tem2==c[j] &&(!t || dep[t]<dep[lca(pos[Tem2],j)])) t=lca(pos[Tem2],j); 92 } 93 se.insert(make_pair(c[j],start[j])); 94 if(t) 95 root[i]=chan(root[i],1,n,start[t],-1); 96 root[i]=chan(root[i],1,n,start[j],1); 97 MD=max(MD,i); 98 } 99 int lastans=0; 100 for(int i=1;i<=m;i++) 101 { 102 if(i==2) 103 int e=1; 104 scanf("%d%d",&x,&d); 105 x^=lastans;d^=lastans; 106 int tim=min(dep[x]+d,MD); 107 printf("%d\n",lastans=que(root[tim],1,n,start[x],en[x])); 108 } 109 } 110 return 0; 111 }