hdu5709Claris Loves Painting主席树 奇妙的DFS序
先不考虑层数限制
一棵树上每个点有个颜色,问一棵子树的颜色数
感觉简单多了是吧
考虑每个点的贡献:自己到根的路径上的一个包含自己的连续段
观察最顶端的点的父亲:
它满足有了额外的同色孩子(咦)
这一条链上需要+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序的更多相关文章
- BZOJ.2434.[NOI2011]阿狸的打字机(AC自动机 树状数组 DFS序)
题目链接 首先不需要存储每个字符串,可以将所有输入的字符依次存进Trie树,对于每个'P',记录该串结束的位置在哪,以及当前节点对应的是第几个串(当前串即根节点到当前节点):对于'B',只需向上跳一个 ...
- 【BZOJ】2434: [Noi2011]阿狸的打字机 AC自动机+树状数组+DFS序
[题意]阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母. 经阿狸研究发现,这个打字机是这样工作的: l 输入小写 ...
- luogu SP8093 后缀自动机+树状数组+dfs序
这题解法很多,简单说几个: 1. 线段树合并,时间复杂度是 $O(nlog^2n)$ 的. 2. 暴力跳 $fail,$ 时间复杂度 $O(n\sqrt n),$ 比较暴力. 3. 建立后缀树后在 $ ...
- 【BZOJ1146】[CTSC2008]网络管理Network 树状数组+DFS序+主席树
[BZOJ1146][CTSC2008]网络管理Network Description M公司是一个非常庞大的跨国公司,在许多国家都设有它的下属分支机构或部门.为了让分布在世界各地的N个部门之间协同工 ...
- BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]
3083: 遥远的国度 Time Limit: 10 Sec Memory Limit: 1280 MBSubmit: 3127 Solved: 795[Submit][Status][Discu ...
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1352 Solved: 780[Submit][Stat ...
- BZOJ 2434: [Noi2011]阿狸的打字机 [AC自动机 Fail树 树状数组 DFS序]
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2545 Solved: 1419[Submit][Sta ...
- 【BZOJ-3881】Divljak AC自动机fail树 + 树链剖分+ 树状数组 + DFS序
3881: [Coci2015]Divljak Time Limit: 20 Sec Memory Limit: 768 MBSubmit: 508 Solved: 158[Submit][Sta ...
- 【BZOJ-1103】大都市meg 树状数组 + DFS序
1103: [POI2007]大都市meg Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2009 Solved: 1056[Submit][Sta ...
随机推荐
- findbugs规则
FindBugs是基于Bug Patterns概念,查找javabytecode(.class文件)中的潜在bug,主要检查bytecode中的bug patterns,如NullPoint空指针检查 ...
- mysql修改初始密码
通过MySQL命令行,可以修改MySQL数据库的密码,下面就为您详细介绍该MySQL命令行,如果您感兴趣的话,不妨一看. 格式:mysqladmin -u用户名 -p旧密码 password 新密码 ...
- html制作细线表格
关于这个细线表格的制作方法,百度一下可能就会有答案告诉你设置这几个值:给table设置border="0" cellspacing="1" bgcolor=&q ...
- Redo Gap 处理与优化
理论背景 当redo data 传送发生中断时就会产生redo gap.当redo 传送恢复正常以后,redo transport service 会自动检测redo gap并发送缺失的redo 到d ...
- JAVA,MYSQL,ORACLE的数据类型对比
MySQL Data Type Oracle Data Type Java BIGINT NUMBER(19, 0) java.lang.Long BIT RAW byte[] BLOB BLOB, ...
- java web路径分析
绝对路径:以/开头的路径就叫做绝对路径,绝对路径在相对于的路径上直接拼接得到最终的路径 相对路径:不以/开头的路径就叫做相对路径,相对路径基于当前所在的路径计算的到最终的路径 硬盘路径:以盘符开头的路 ...
- fragment getActivity()空指针
Fragment弹出toast,时不时出现getActivity()空指针,具体原因未查到. 解决办法: if (null == fragment || !fragment.isAdded()) { ...
- Java中的数组和方法
3.1 数组的定义和使用 数组(Array)是用来存储一组相同数据类型数据的集合.数组中的每个数据称为一个元素(element),数组可以分为一维数组,二维数组和多维数组.我们 主要讲解一维数组和二维 ...
- 微软开业网站----精华 http://www.microsoft.com/opensource/directory.aspx
http://www.microsoft.com/opensource/directory.aspx
- [PE182]RSA encryption
https://projecteuler.net/problem=182 题意: 找出满足下列条件的所有$e$ 的和, - $1 < e < \varphi \left( {1009,36 ...