题目大意:给你一棵n个点的树,每个点有颜色,m次询问,每次询问一个点x的子树内深度不超过depth[x]+d的节点的颜色数量,强制在线。(n,m<=100000,多组数据,保证n,m总和不超过500000)

思路:若不考虑深度限制,我们可以先给每个点赋点权1,再把每种颜色的节点按dfs序排序后相邻的节点的LCA的点权减1,每次求子树和即可回答询问,若有限制深度,我们可以按深度顺序把点一个个加入树中,每种颜色用个set维护,强制在线只要把求子树和的线段树可持久化就可以了,总复杂度O(nlogn)。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
using namespace std;
inline int read()
{
int x;char c;
while((c=getchar())<''||c>'');
for(x=c-'';(c=getchar())>=''&&c<='';)x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 100000
#define K 17
#define ND 8000000
struct edge{int nx,t;}e[MN+];
int h[MN+],en,c[MN+],d[MN+],l[MN+],r[MN+],cnt,fa[K][MN+],p[MN+],rt[MN+],tn;
class stcmp{public:inline bool operator()(int a,int b){return l[a]<l[b];}};
set<int,stcmp> st[MN+];
set<int,stcmp>::iterator x,y,z;
struct node{int l,r,s;}t[ND+];
int renew(int x,int l,int r,int k,int z)
{
int p=++tn,mid=l+r>>;
if(l==r)return t[p]=(node){,,t[x].s+z},p;
if(k<=mid)return t[p]=(node){renew(t[x].l,l,mid,k,z),t[x].r,t[x].s+z},p;
return t[p]=(node){t[x].l,renew(t[x].r,mid+,r,k,z),t[x].s+z},p;
}
int query(int x,int l,int r,int L,int R)
{
if(l==L&&r==R)return t[x].s;
int mid=l+r>>;
if(R<=mid)return query(t[x].l,l,mid,L,R);
if(L>mid)return query(t[x].r,mid+,r,L,R);
return query(t[x].l,l,mid,L,mid)+query(t[x].r,mid+,r,mid+,R);
}
inline void ins(int x,int y){e[++en]=(edge){h[x],y};h[x]=en;}
void dfs(int x)
{
l[x]=++cnt;
for(int i=h[x];i;i=e[i].nx)d[e[i].t]=d[x]+,dfs(e[i].t);
r[x]=cnt;
}
bool cmp(int a,int b){return d[a]<d[b];}
int lca(int x,int y)
{
int dx=d[x]-d[y],i;
if(dx<)dx=-dx,swap(x,y);
for(i=;dx;dx>>=,++i)if(dx&)x=fa[i][x];
if(x==y)return x;
for(i=K;i--;)if(fa[i][x]!=fa[i][y])x=fa[i][x],y=fa[i][y];
return fa[][x];
}
int main()
{
int T,n,m,i,j,t;
for(T=read();T--;)
{
n=read();m=read();
for(i=;i<=n;++i)c[i]=read(),p[i]=i,st[i].clear();
memset(h,t=tn=en=cnt=,sizeof(int)*(n+));
for(i=;i<=n;++i)ins(fa[][i]=read(),i);
for(i=;i<K;++i)for(j=;j<=n;++j)fa[i][j]=fa[i-][fa[i-][j]];
dfs();sort(p+,p+n+,cmp);
for(i=;i<=n;++i)
{
t=renew(t,,n,l[p[i]],);
st[c[p[i]]].insert(p[i]);
x=y=z=st[c[p[i]]].find(p[i]);--x;++z;
if(y!=st[c[p[i]]].begin()&&z!=st[c[p[i]]].end())t=renew(t,,n,l[lca(*x,*z)],);
if(y!=st[c[p[i]]].begin())t=renew(t,,n,l[lca(*x,*y)],-);
if(z!=st[c[p[i]]].end())t=renew(t,,n,l[lca(*y,*z)],-);
rt[d[p[i]]]=t;
}
for(t=;m--;)
{
i=read()^t;j=read()^t;
printf("%d\n",t=query(rt[d[i]+j>d[p[n]]?d[p[n]]:d[i]+j],,n,l[i],r[i]));
}
}
}

[BZOJ]2017省队十连测推广赛1 T2.七彩树的更多相关文章

  1. [BZOJ]2017省队十连测推广赛1

    听学长说有比赛就随便打一打. A.普通计算姬 题目大意:给出一棵带权树,支持一下两种操作:1.修改一个点的权值:2.给出l,r,询问以点l为根的子树和.点l+1为根的子树和.点l+2为根的子树和--点 ...

  2. [bzoj省选十连测推广赛2]T2七彩树

    抄自:http://blog.csdn.net/coldef/article/details/61412577 当时看了就不会,看了别人的题解不懂怎么维护,最后抄了个代码....... 给定一棵n个点 ...

  3. bzoj省选十连测推广赛

    A.普通计算姬 题意:给丁一棵树,每个点有一个权值,用sum(x)表示以x为根的子树的权值和,要求支持两种操作: 1 u v  :修改点u的权值为v. 2 l  r   :  求∑sum[i] l&l ...

  4. bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树

    [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 93  Solved: 53[Submit][Status][ ...

  5. bzoj 5216: [Lydsy2017省队十连测]公路建设

    5216: [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 66  Solved: 37[Submit][St ...

  6. Lydsy2017省队十连测

    5215: [Lydsy2017省队十连测]商店购物 可能FFT学傻了,第一反应是前面300*300背包,后面FFT... 实际上前面背包,后面组合数即可.只是这是一道卡常题,需要注意常数.. //A ...

  7. bzoj 5218: [Lydsy2017省队十连测]友好城市

    题意: 这题显然直接tarjan是做不了的. 这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客 于是结合莫队,我们有了个暴力. 发现主要瓶颈是dfs过程中找最小的未经过的点,我们用 ...

  8. 【BZOJ 5222】[Lydsy2017省队十连测]怪题

    题目大意: 传送门 给一个长度为$n(n<=200)$的数列$h$,再给$m$个可以无限使用的操作,第$i$个操作为给长度为花费$c_i$的价值给长度为$l_i$的数列子序列+1或-1,求将数列 ...

  9. bzoj 5217: [Lydsy2017省队十连测]航海舰队

    Description Byteasar 组建了一支舰队!他们现在正在海洋上航行着.海洋可以抽象成一张n×m 的网格图,其中有些位置是" .",表示这一格是海水,可以通过:有些位置 ...

随机推荐

  1. hi-nginx-1.4.2发布,多项重要更新

    支持多种编程语言混合开发web应用的通用服务器hi-nginx-1.4.2已经发布了. 此次发布包含多项重要更新: 支持python2和3,通过编译选项--with-http-hi-python-ve ...

  2. python 面向对象设计思想发展史

    这篇主要说的是程序设计思想发展历史,分为概述和详细发展历史 一,概述 1940年以前:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的 指令和数 据.简单来 ...

  3. JAVA_SE基础——63.String类的常用方法

    获取方法int length()  获取字符串的长度char charAt(int index) 获取特定位置的字符 (角标越界)int indexOf(String str) 查找子串第一次出现的索 ...

  4. Python之旅.第三章.函数3.27

    一.形参与实参 1.形参与实参是什么? 形参(形式参数):指的是 在定义函数时,括号内定义的参数,形参其实就变量名 实参(实际参数),指的是 在调用函数时,括号内传入的值,实参其实就变量的值 x,y是 ...

  5. 在windows环境下安装redis和phpredis的扩展

    在windows环境下安装redis和phpredis的扩展 1.首先配置php: 需要在windows的集成环境中找到php的扩展文件夹,ext,然后在网上寻找自己的php对应的.dll文件 比如说 ...

  6. 【转】optach学习

    [转自:https://yq.aliyun.com/articles/28007,仅作学习用途] 摘要: Opatch 是oracle公司开发的安装,卸载,检测patch冲突的工具,管理oracle所 ...

  7. c# 几种深拷贝方式的比较

    public static class Tools { //利用 BinaryFormatter 实现深拷贝 public static T DeepCopyByBinary<T>(thi ...

  8. python的命名空间

    Python的命名空间是Python程序猿必须了解的内容,对Python命名空间的学习,将使我们在本质上掌握一些Python中的琐碎的规则. 接下来我将分四部分揭示Python命名空间的本质:一.命名 ...

  9. sql优化基础篇

    优化的步骤: 0.先sql运行看看是否真的很慢,注意设置SQL_NO_CACHE 1.where条件单表查,锁定最小返回记录表.这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始 ...

  10. zoj 3950 how many nines

    https://vjudge.net/problem/ZOJ-3950 题意: 给出两个日期,计算从第一个日期开始到第二个日期,每一天的日期中的9加起来一共有多少个. 思路: 看题解补的题.首先看这题 ...