先不考虑层数限制

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

感觉简单多了是吧

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

观察最顶端的点的父亲:

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

这一条链上需要+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 ;
}

hdu5709Claris Loves Painting主席树 奇妙的DFS序的更多相关文章

  1. BZOJ.2434.[NOI2011]阿狸的打字机(AC自动机 树状数组 DFS序)

    题目链接 首先不需要存储每个字符串,可以将所有输入的字符依次存进Trie树,对于每个'P',记录该串结束的位置在哪,以及当前节点对应的是第几个串(当前串即根节点到当前节点):对于'B',只需向上跳一个 ...

  2. 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序

    [题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...

  3. luogu SP8093 后缀自动机+树状数组+dfs序

    这题解法很多,简单说几个: 1. 线段树合并,时间复杂度是 $O(nlog^2n)$ 的. 2. 暴力跳 $fail,$ 时间复杂度 $O(n\sqrt n),$ 比较暴力. 3. 建立后缀树后在 $ ...

  4. 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树

    [BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...

  5. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  6. BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1352  Solved: 780[Submit][Stat ...

  7. BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]

    2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 2545  Solved: 1419[Submit][Sta ...

  8. 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序

    3881: [Coci2015]Divljak Time Limit: 20 Sec  Memory Limit: 768 MBSubmit: 508  Solved: 158[Submit][Sta ...

  9. 【BZOJ-1103】大都市meg 树状数组 + DFS序

    1103: [POI2007]大都市meg Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2009  Solved: 1056[Submit][Sta ...

随机推荐

  1. findbugs规则

    FindBugs是基于Bug Patterns概念,查找javabytecode(.class文件)中的潜在bug,主要检查bytecode中的bug patterns,如NullPoint空指针检查 ...

  2. mysql修改初始密码

    通过MySQL命令行,可以修改MySQL数据库的密码,下面就为您详细介绍该MySQL命令行,如果您感兴趣的话,不妨一看. 格式:mysqladmin -u用户名 -p旧密码 password 新密码 ...

  3. html制作细线表格

    关于这个细线表格的制作方法,百度一下可能就会有答案告诉你设置这几个值:给table设置border="0" cellspacing="1" bgcolor=&q ...

  4. Redo Gap 处理与优化

    理论背景 当redo data 传送发生中断时就会产生redo gap.当redo 传送恢复正常以后,redo transport service 会自动检测redo gap并发送缺失的redo 到d ...

  5. JAVA,MYSQL,ORACLE的数据类型对比

    MySQL Data Type Oracle Data Type Java BIGINT NUMBER(19, 0) java.lang.Long BIT RAW byte[] BLOB BLOB,  ...

  6. java web路径分析

    绝对路径:以/开头的路径就叫做绝对路径,绝对路径在相对于的路径上直接拼接得到最终的路径 相对路径:不以/开头的路径就叫做相对路径,相对路径基于当前所在的路径计算的到最终的路径 硬盘路径:以盘符开头的路 ...

  7. fragment getActivity()空指针

    Fragment弹出toast,时不时出现getActivity()空指针,具体原因未查到. 解决办法: if (null == fragment || !fragment.isAdded()) { ...

  8. Java中的数组和方法

    3.1 数组的定义和使用 数组(Array)是用来存储一组相同数据类型数据的集合.数组中的每个数据称为一个元素(element),数组可以分为一维数组,二维数组和多维数组.我们 主要讲解一维数组和二维 ...

  9. 微软开业网站----精华 http://www.microsoft.com/opensource/directory.aspx

    http://www.microsoft.com/opensource/directory.aspx

  10. [PE182]RSA encryption

    https://projecteuler.net/problem=182 题意: 找出满足下列条件的所有$e$ 的和, - $1 < e < \varphi \left( {1009,36 ...