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  } 

 

posted @ 2017-07-15 20:47  汪立超  阅读(535)  评论(0编辑  收藏  举报