# [BZOJ4771]七彩树(主席树)

https://blog.csdn.net/KsCla/article/details/78249148

 1 #include<set>
2 #include<cstdio>
3 #include<vector>
4 #include<algorithm>
5 #define rep(i,l,r) for (int i=(l); i<=(r); i++)
6 #define For(i,x) for (int i=h[x],k; i; i=nxt[i])
7 typedef long long ll;
8 using namespace std;
9
10 const int N=100010,M=10000010;
11 int T,n,m,u,v,cnt,ans,tim,nd,x,d,co[N],dep[N],h[N],to[N],nxt[N];
12 int ls[M],rs[M],sm[M],fa[N][19],L[N],R[N],pos[N],rt[N];
13 vector<int>a[N];
14 set<int>c[N];
15
16 void add(int u,int v){ to[++cnt]=v; nxt[cnt]=h[u]; h[u]=cnt; }
17
18 void dfs(int x){
19     rep(i,1,18) fa[x][i]=fa[fa[x][i-1]][i-1];
20     dep[x]=dep[fa[x][0]]+1; L[x]=++tim;
21     pos[tim]=x; a[dep[x]].push_back(x);
22     For(i,x) dfs(k=to[i]); R[x]=tim;
23 }
24
25 int lca(int u,int v){
26     if (dep[u]<dep[v]) swap(u,v);
27     int t=dep[u]-dep[v];
28     for (int i=18; ~i; i--) if (t&(1<<i)) u=fa[u][i];
29     if (u==v) return u;
30     for (int i=18; ~i; i--) if (fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
31     return fa[u][0];
32 }
33
34 void ins(int &x,int y,int L,int R,int pos,int k){
35     x=++nd; ls[x]=ls[y]; rs[x]=rs[y]; sm[x]=sm[y]+k;
36     if (L==R) return;
37     int mid=(L+R)>>1;
38     if (pos<=mid) ins(ls[x],ls[y],L,mid,pos,k);
39         else ins(rs[x],rs[y],mid+1,R,pos,k);
40 }
41
42 int que(int x,int y,int L,int R,int l,int r){
43     if (!y) return 0;
44     if (L==l && r==R) return sm[y]-sm[x];
45     int mid=(L+R)>>1;
46     if (r<=mid) return que(ls[x],ls[y],L,mid,l,r);
47     else if (l>mid) return que(rs[x],rs[y],mid+1,R,l,r);
48         else return que(ls[x],ls[y],L,mid,l,mid)+que(rs[x],rs[y],mid+1,R,mid+1,r);
49 }
50
51 int main(){
52     freopen("bzoj4771.in","r",stdin);
53     freopen("bzoj4771.out","w",stdout);
54     for (scanf("%d",&T); T--; ){
55         scanf("%d%d",&n,&m);
56         rep(i,1,n) h[i]=0; cnt=tim=ans=nd=0;
57         rep(i,1,n) scanf("%d",&co[i]);
59         rep(i,1,n) a[i].clear(),c[co[i]].clear();
60         dfs(1);
61         rep(i,1,n){
62             rt[i]=rt[i-1]; int ed=a[i].size()-1;
63             rep(j,0,ed){
64                 int x=a[i][j]; ins(rt[i],rt[i],1,n,L[x],1); c[co[x]].insert(L[x]);
65                 set<int>::iterator it=c[co[x]].find(L[x]);
66                 int pre=0,suf=0; it++;
67                 if (it!=c[co[x]].end()) suf=*it; it--;
68                 if (it!=c[co[x]].begin()) it--,pre=*it;
69                 if (pre && suf) ins(rt[i],rt[i],1,n,L[lca(pos[pre],pos[suf])],1);
70                 if (pre) ins(rt[i],rt[i],1,n,L[lca(pos[pre],x)],-1);
71                 if (suf) ins(rt[i],rt[i],1,n,L[lca(pos[suf],x)],-1);
72             }
73         }
74         while (m--){
75             scanf("%d%d",&x,&d); x^=ans; d^=ans;
76             printf("%d\n",ans=que(rt[dep[x]-1],rt[dep[x]+d],1,n,L[x],R[x]));
77         }
78     }
79     return 0;
80 }

posted @ 2018-12-11 20:02  HocRiser  阅读(180)  评论(0编辑  收藏  举报