先不考虑层数限制

一棵树上每个点有个颜色,问一棵子树的颜色数

感觉简单多了是吧

考虑每个点的贡献:自己到根的路径上的一个包含自己的连续段

观察最顶端的点的父亲:

它满足有了额外的同色孩子(咦)

这一条链上需要+1(@miaom)

如果差分,就是在这个点+1(@miaom),在最近的有同色孩子的父亲-1,求子树和

最近的有同色孩子的父亲?

根据直觉,它一定是dfs序上和这个点相邻的同色点和这个点的lca

没了

再加上层数限制

相当于一定要在一定的深度以内

所以开主席树保持可持久化(怎么不能离线啊,好烦啊)

 #include <bits/stdc++.h>
#define LOG 19
#define mid (l+r>>1)
using namespace std;
int NODE,n,m,p,q,E,TIME,x,d;
int dep[],nex[],fir[],Fir[],Nex[];
int fa[][],to[];//,ne[200001];
int tr[],ls[],rs[];
int c[],root[],start[],en[],pos[];
void dfs(int now,int fat)
{
dep[now]=dep[fat]+;start[now]=++TIME;pos[TIME]=now;
Nex[now]=Fir[dep[now]];Fir[dep[now]]=now;
fa[now][]=fat;
for(int i=;fa[now][i-];i++) fa[now][i]=fa[fa[now][i-]][i-];
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fat)
dfs(to[i],now);
en[now]=TIME;
}
int lca(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int delta=dep[x]-dep[y],i=;delta;delta>>=,++i)
if(delta&) x=fa[x][i];
for(int i=LOG;i>=;i--)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return (x==y)?x:fa[x][];
}
int chan(int acc,int l,int r,int x,int y)
{
int now=++NODE;
if(l==r)
{
tr[now]=tr[acc]+y;
return now;
}
if(x<=mid) ls[now]=chan(ls[acc],l,mid,x,y),rs[now]=rs[acc];
else rs[now]=chan(rs[acc],mid+,r,x,y),ls[now]=ls[acc];
tr[now]=tr[ls[now]]+tr[rs[now]];
return now;
}
void add(int x,int y)
{
to[++E]=y;nex[E]=fir[x];fir[x]=E;
}
int que(int now,int l,int r,int x,int y)
{
if(l==x && r==y)
return tr[now];
int ret=;
if(x<=mid)
ret+=que(ls[now],l,mid,x,min(y,mid));
if(y>mid)
ret+=que(rs[now],mid+,r,max(mid+,x),y);
return ret;
}
set<pair<int,int> > se;
int main()
{
int T;
for(scanf("%d",&T);T;T--)
{
scanf("%d%d",&n,&m);E=;TIME=;NODE=;
se.clear();
for(int i=;i<=n;i++)
scanf("%d",&c[i]);
for(int i=;i<=n;i++)
fir[i]=,Fir[i]=;
for(int i=;i<=n;i++)
for(int j=;j<=;j++)
fa[i][j]=;
for(int i=;i<n;i++)
scanf("%d",&q),add(q,i+);
dfs(,);root[]=;tr[]=;ls[]=;rs[]=;
int MD=;
for(int i=;i<=n;root[i+]=root[i],i++)
for(int j=Fir[i];j;j=Nex[j])
{
int t=;
pair <int,int> tem=*se.lower_bound(make_pair(c[j],start[j]));
int tem1=tem.first;
int Tem1=tem.second;
if(tem1==c[j]) t=lca(pos[Tem1],j);
if(se.lower_bound(make_pair(c[j],start[j]))!=se.begin())
{
tem=*(--se.lower_bound(make_pair(c[j],start[j])));
int tem2=tem.first;
int Tem2=tem.second;
if(tem2==c[j] &&(!t || dep[t]<dep[lca(pos[Tem2],j)])) t=lca(pos[Tem2],j);
}
se.insert(make_pair(c[j],start[j]));
if(t)
root[i]=chan(root[i],,n,start[t],-);
root[i]=chan(root[i],,n,start[j],);
MD=max(MD,i);
}
int lastans=;
for(int i=;i<=m;i++)
{
if(i==)
int e=;
scanf("%d%d",&x,&d);
x^=lastans;d^=lastans;
int tim=min(dep[x]+d,MD);
printf("%d\n",lastans=que(root[tim],,n,start[x],en[x]));
}
}
return ;
}

最新文章

  1. C++设计模式-Mediator中介者模式
  2. php学习5-时间和日期
  3. [转]AS3的垃圾回收
  4. 使用engine关键字指定该表使用哪个engine
  5. 用几条shell命令快速去重10G数据
  6. codeforces 192e
  7. [Effective C++ --006]若不能使用编译器自动生成的函数,就该明确拒绝
  8. LINQ 内链接 左链接 右链接
  9. c#提出中文首字母
  10. A2W和W2A :很好的多字节和宽字节字符串的转换宏
  11. JavaWeb总结(二)—HttpServletResponse对象
  12. Angular页面选项卡切换要注意的toggleClass
  13. python的logging模块之读取yaml配置文件。
  14. ps技术--批量给图片加水印
  15. https和http 调用过程中请求头 referrer 获取不到的问题
  16. Vue组件中的问题
  17. C# json帮助类,JsonHelper,Table转JSon,JSon转Table
  18. Java开发MIS系统需要的技术及其作用
  19. Windows 上 Nginx 路径的陷阱
  20. pythonweb框架Flask学习笔记02-一个简单的小程序

热门文章

  1. lucene内置的评分函数
  2. Nginx中如何限制某个IP同一时间段的访问次数
  3. 「UVA557」 Burger(概率
  4. 【LeetCode】070. Climbing Stairs
  5. 1130 host is not allowed to connect to
  6. 关于Android的HAL的一些理解
  7. POJ3660(foyld闭包问题)
  8. git学习 7 git每次push都输入用户名 密码
  9. sql web Admin 源码.net 升级
  10. kindeditor Springmvc 整和解决图片上传问题