先不考虑层数限制

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

感觉简单多了是吧

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

观察最顶端的点的父亲:

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

这一条链上需要+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. matlab的代码注释

    1.注释一块代码: %{ 此处代码块 %} 2.注释数行代码: 先选中,然后用组合键Ctrl+R 取消注释,用组合键Ctrl+T 3.双%%的作用:代码分块运行,点击双%%之间的代码,再点Run Se ...

  2. 关于MVC模板渲染的一点小事type="text/template"

    先上一个demo,简单粗暴,请自便 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...

  3. Linux 文本的^M问题

    很多人在windows中使用文本编辑器编辑好文本后,传送到linux系统后,使用vi工具打开后发现每一行文本最后都有一个^M号,原因是: 在DOS使用的换行符为 \r\n,我们称为CR(\r)与LF( ...

  4. highcharts 图例全选按钮方法

    $('#uncheckAll').click(function(){ var chart = $('#container').highcharts(); var series = chart.seri ...

  5. 「HNOI2008」「LuoguP3197」越狱(数论

    题目描述 原题来自:HNOI 2008 监狱有连续编号为 111 到 nnn 的 nnn 个房间,每个房间关押一个犯人.有 mmm 种宗教,每个犯人可能信仰其中一种.如果相邻房间的犯人信仰的宗教相同, ...

  6. Wmware Player中Linux挂载U盘

    菜单(Player)中有一项是可移动设备,中选择U盘,然后选择连接(断开主机), 然后在命令行中敲入 fdisk -l 正常情况下是sda是硬盘的信息,然后将会看到一个单蹦的sdb4的信息(sdb4可 ...

  7. 重学JAVA基础(一):PATH和CLASSPATH

    我想大多数Java初学者都会遇到的问题,那就是怎么配置环境,执行java -jar xxx.jar  都会报NoClassDefFindError,我在最开始学习的时候,也遇到了这些问题. 1.PAT ...

  8. JQuery Mobile的页面

    1.JQuery Mobile的页面结构如下图: page:是在浏览器中显示的页面 header:创建页面上方的工具栏(常用于标题和搜索按钮) content:定义了页面的内容,比如文本, 图片,表单 ...

  9. python3中,pycharm中怎么连接数据库

    因为python3现在还不能直接连接数据库,所有如果想连接,就只能通过以下方法: 在APP中的,__init__.py中,添加以下代码就可以: import pymysql pymysql.insta ...

  10. [poj2151]Check the difficulty of problems概率dp

    解题关键:主要就是概率的推导以及至少的转化,至少的转化是需要有前提条件的. 转移方程:$dp[i][j][k] = dp[i][j - 1][k - 1]*p + dp[i][j - 1][k]*(1 ...