# bzoj4771 七彩树

  1 /**************************************************************
2     Problem: 4771
3     User: hzoier
4     Language: C++
5     Result: Accepted
6     Time:2176 ms
7     Memory:118204 kb
8 ****************************************************************/
9 #include<cstdio>
10 #include<cstring>
11 #include<algorithm>
12 #include<vector>
13 #include<set>
14 using namespace std;
15 const int maxn=100010,maxm=maxn<<6;
16 void clear(int);
17 void bfs();
18 int LCA(int,int);
19 void build(int,int,int&);
20 void query(int,int,int);
21 int copy(int);
22 int sm[maxm]={0},lc[maxm]={0},rc[maxm]={0},vis[maxm]={0},root[maxn],cnt=0,tim;
23 vector<int>G[maxn];
24 int f[maxn][20],d[maxn],dfn[maxn],size[maxn],q[maxn];
25 struct cmp{bool operator()(int x,int y)const{return dfn[x]<dfn[y];}};
26 set<int,cmp>st[maxn];
27 int T,n,m,lgn,a[maxn],x,s,t,k,ans;
28 int main(){
29     scanf("%d",&T);
30     while(T--){
31         scanf("%d%d",&n,&m);
32         clear(n);
33         for(int i=1;i<=n;i++)scanf("%d",&a[i]);
34         for(int i=2;i<=n;i++){
35             scanf("%d",&f[i][0]);
36             G[f[i][0]].push_back(i);
37         }
38         bfs();
39         for(int j=1;j<=lgn;j++)for(int i=1;i<=n;i++)f[i][j]=f[f[i][j-1]][j-1];
40         for(int i=1;i<=n;i++){
41             x=q[i];
42             if(!root[d[x]])root[d[x]]=root[d[x]-1];
43             tim=d[x];
44             k=1;
45             t=dfn[x];
46             build(1,n,root[d[x]]);
47             set<int,cmp>::iterator u=st[a[x]].lower_bound(x),v=st[a[x]].upper_bound(x);
48             if(u==st[a[x]].begin())u=st[a[x]].end();
49             else if(u!=st[a[x]].end())u--;
50             else if(!st[a[x]].empty()&&dfn[*st[a[x]].rbegin()]<dfn[x])u=st[a[x]].find(*st[a[x]].rbegin());
51             if(u!=st[a[x]].end()&&v!=st[a[x]].end()){
52                 t=dfn[LCA(*u,*v)];
53                 build(1,n,root[d[x]]);
54             }
55             k=-1;
56             if(u!=st[a[x]].end()){
57                 t=dfn[LCA(*u,x)];
58                 build(1,n,root[d[x]]);
59             }
60             if(v!=st[a[x]].end()){
61                 t=dfn[LCA(x,*v)];
62                 build(1,n,root[d[x]]);
63             }
64             st[a[x]].insert(x);
65         }
66         for(int i=1;i<=n;i++)if(!root[i])root[i]=root[i-1];
67         while(m--){
68             scanf("%d%d",&x,&k);
69             x^=ans;k^=ans;
70             s=dfn[x];
71             t=dfn[x]+size[x]-1;
72             ans=0;
73             query(1,n,root[min(d[x]+k,n)]);
74             printf("%d\n",ans);
75         }
76     }
77     return 0;
78 }
79 void clear(int n){
80     fill(sm,sm+cnt+1,0);
81     fill(lc,lc+cnt+1,0);
82     fill(rc,rc+cnt+1,0);
83     fill(vis,vis+cnt+1,0);
84     cnt=tim=0;
85     fill(root,root+n+1,0);
86     for(int i=0;i<=n;i++){
87         G[i].clear();
88         memset(f[i],0,sizeof(f[i]));
89         st[i].clear();
90     }
91     fill(d,d+n+1,0);
92     fill(dfn,dfn+n+1,0);
93     fill(size,size+n+1,0);
94     lgn=ans=0;
95 }
96 void bfs(){
98     q[tail++]=1;
101         dfn[x]=size[x]=1;
102         d[x]=d[f[x][0]]+1;
103         while((1<<lgn)<d[x])lgn++;
104         for(int i=0;i<(int)G[x].size();i++)q[tail++]=G[x][i];
105     }
106     for(int i=n;i>1;i--){
107         x=q[i];
108         dfn[x]+=size[f[x][0]];
109         size[f[x][0]]+=size[x];
110     }
111     for(int i=2;i<=n;i++)dfn[q[i]]+=dfn[f[q[i]][0]]-1;
112 }
113 int LCA(int x,int y){
114     if(d[x]!=d[y]){
115         if(d[x]<d[y])swap(x,y);
116         for(int i=lgn;i>=0;i--)if(d[f[x][i]]>=d[y])x=f[x][i];
117     }
118     if(x==y)return x;
119     for(int i=lgn;i>=0;i--)if(f[x][i]!=f[y][i]){
120         x=f[x][i];
121         y=f[y][i];
122     }
123     return f[x][0];
124 }
125 void build(int l,int r,int &rt){
126     if(vis[rt]<tim)rt=copy(rt);
127     sm[rt]+=k;
128     if(l==r)return;
129     int mid=(l+r)>>1;
130     if(t<=mid)build(l,mid,lc[rt]);
131     else build(mid+1,r,rc[rt]);
132 }
133 void query(int l,int r,int rt){
134     if(!rt)return;
135     if(s<=l&&t>=r){
136         ans+=sm[rt];
137         return;
138     }
139     int mid=(l+r)>>1;
140     if(s<=mid)query(l,mid,lc[rt]);
141     if(t>mid)query(mid+1,r,rc[rt]);
142 }
143 int copy(int rt){
144     int x=++cnt;
145     sm[x]=sm[rt];
146     lc[x]=lc[rt];
147     rc[x]=rc[rt];
148     vis[x]=tim;
149     return x;
150 }
View Code

233333333
posted @ 2017-03-23 17:26  AntiLeaf  阅读(139)  评论(0编辑  收藏  举报