# 【BZOJ4771】七彩树

1
5 8
1 3 3 2 2
1 1 3 3
1 0
0 0
3 0
1 3
2 1
2 0
6 2
4 1

## Sample Output

1
2
3
1
1
2
1
1

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
const int maxn=100010;
int n,m,cnt,tot,ans;
set<int> S[maxn];
set<int>::iterator it;
struct node
{
int ls,rs,siz;
}s[maxn*50];
void dfs(int x)
{
p[x]=++q[0],Q[q[0]]=x;
q[x]=q[0];
}
inline int lca(int a,int b)
{
if(dep[a]<dep[b])	swap(a,b);
for(int i=Log[dep[a]-dep[b]];i>=0;i--)	if(dep[fa[i][a]]>=dep[b])	a=fa[i][a];
if(a==b)	return a;
for(int i=Log[dep[a]];i>=0;i--)	if(fa[i][a]!=fa[i][b])	a=fa[i][a],b=fa[i][b];
return fa[0][a];
}
bool cmp(int a,int b)
{
return dep[a]<dep[b];
}
void insert(int x,int &y,int l,int r,int a,int b)
{
y=++tot,s[y].ls=s[y].rs=s[y].siz=0;
s[y].siz=s[x].siz+b;
if(l==r)	return ;
int mid=(l+r)>>1;
if(a<=mid)	s[y].rs=s[x].rs,insert(s[x].ls,s[y].ls,l,mid,a,b);
else	s[y].ls=s[x].ls,insert(s[x].rs,s[y].rs,mid+1,r,a,b);
}
int query(int l,int r,int x,int a,int b)
{
if(!x||(a<=l&&r<=b))	return s[x].siz;
int mid=(l+r)>>1;
if(b<=mid)	return query(l,mid,s[x].ls,a,b);
if(a>mid)	return query(mid+1,r,s[x].rs,a,b);
return query(l,mid,s[x].ls,a,b)+query(mid+1,r,s[x].rs,a,b);
}
inline int rd()
{
int ret=0,f=1;	char gc=getchar();
while(gc<'0'||gc>'9')	{if(gc=='-')	f=-f;	gc=getchar();}
while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
{
}
void work()
{
n=rd(),m=rd(),tot=cnt=ans=q[0]=0;
int i,j,a,b;
memset(rt,0,sizeof(rt));
memset(fa,0,sizeof(fa));
for(i=1;i<=n;i++)	v[i]=rd(),S[i].clear(),pd[i]=i;
dep[1]=1,dfs(1);
for(j=1;(1<<j)<=n;j++)	for(i=1;i<=n;i++)	fa[j][i]=fa[j-1][fa[j-1][i]];
sort(pd+1,pd+n+1,cmp);
for(i=1;i<=n;i++)
{
j=pd[i],a=b=0,it=S[v[j]].lower_bound(p[j]);
insert(rt[dep[pd[i-1]]],rt[dep[j]],1,n,p[j],1);
if(it!=S[v[j]].end())	b=Q[(*it)],insert(rt[dep[j]],rt[dep[j]],1,n,p[lca(b,j)],-1);
if(it!=S[v[j]].begin())	it--,a=Q[(*it)],insert(rt[dep[j]],rt[dep[j]],1,n,p[lca(a,j)],-1);
if(a&&b)	insert(rt[dep[j]],rt[dep[j]],1,n,p[lca(a,b)],1);
S[v[j]].insert(p[j]);
}
for(i=1;i<=m;i++)
{
a=rd()^ans,b=rd()^ans;
ans=query(1,n,rt[min(dep[a]+b,dep[pd[n]])],p[a],q[a]);
printf("%d\n",ans);
//ans=0;
}
}
int main()
{
int T=rd();
while(T--)	work();
return 0;
}//1 4 4 4 2 3 2  1 2 1  3 2 2 2 4 1 4 1 
posted @ 2017-10-05 14:52  CQzhangyu  阅读(807)  评论(1编辑  收藏  举报