题目大意:给你一棵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. C程序第一次作业

    1-1 计算两数的和与差 1 设计思路 (1)主要描述题目算法 第一步:利用指针psum接收sum的地址,指针pdiff接收diff的地址,因此 * psum为sum, * pdiff为diff. 第 ...

  2. python实现京东秒杀

    # _*_coding:utf-8_*_ from selenium import webdriver import datetime import time driver = webdriver.C ...

  3. 【iOS】OC-UTC日期字符串格式化

    NSLog(@"%@",[NSDate date]); NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init ...

  4. tornado web高级开发项目

    抽屉官网:http://dig.chouti.com/ 一.配置(settings) settings = { 'template_path': 'views', #模板文件路径 'static_pa ...

  5. 构建微服务开发环境7————使用Github管理项目代码的版本

    [内容指引] 1.注册GitHub帐号: 2.下载Github Desktop客户端: 3.macOS安装Github Desktop客户端: 4.windows安装Github Desktop客户端 ...

  6. Mego(07) - 关系配置

    这个是本框架的重要功能,该关系就是指对象中的复杂对象或集合属性,该关系与EF中的关系是有区别的.EF中强调关系的成对出现,这是由于数据库关系的思想决定的.然而Mego更接近与对象化逻辑,我们只关心当前 ...

  7. 零基础大数据入门教程:Java调用阿里云短信通道服务

    这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1 ...

  8. MySQL8.0 原子DDL

    Edit MySQL8.0 原子DDL 简介 MySQL8.0 开始支持原子 DDL(atomic DDL),数据字典的更新,存储引擎操作,写二进制日志结合成了一个事务.在没有原子DDL之前,DROP ...

  9. 实现GridControl的行单元格非顺序跳转

    用GridControl控件添加数据的时候发现,有一些字段过多但是并不是每个字段都需要用户输入,每个单元格都回车跳转的时候不仅浪费时间,而且用户体验也不好,就需要单元格跳转的时候,不需要的字段可以隔过 ...

  10. Couchbase忘记登录密码怎么办

    以下都为root用户操作: 1.先关闭couchbase /opt/couchbase/etc/couchbase_init.d stop 2.切换到下面的路径,删除这个目录下除logs的所有文件,按 ...