[BZOJ]2017省队十连测推广赛1 T2.七彩树
题目大意:给你一棵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.七彩树的更多相关文章
- [BZOJ]2017省队十连测推广赛1
听学长说有比赛就随便打一打. A.普通计算姬 题目大意:给出一棵带权树,支持一下两种操作:1.修改一个点的权值:2.给出l,r,询问以点l为根的子树和.点l+1为根的子树和.点l+2为根的子树和--点 ...
- [bzoj省选十连测推广赛2]T2七彩树
抄自:http://blog.csdn.net/coldef/article/details/61412577 当时看了就不会,看了别人的题解不懂怎么维护,最后抄了个代码....... 给定一棵n个点 ...
- bzoj省选十连测推广赛
A.普通计算姬 题意:给丁一棵树,每个点有一个权值,用sum(x)表示以x为根的子树的权值和,要求支持两种操作: 1 u v :修改点u的权值为v. 2 l r : 求∑sum[i] l&l ...
- bzoj 5216 [Lydsy2017省队十连测]公路建设 线段树维护 最小生成树
[Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 93 Solved: 53[Submit][Status][ ...
- bzoj 5216: [Lydsy2017省队十连测]公路建设
5216: [Lydsy2017省队十连测]公路建设 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 66 Solved: 37[Submit][St ...
- Lydsy2017省队十连测
5215: [Lydsy2017省队十连测]商店购物 可能FFT学傻了,第一反应是前面300*300背包,后面FFT... 实际上前面背包,后面组合数即可.只是这是一道卡常题,需要注意常数.. //A ...
- bzoj 5218: [Lydsy2017省队十连测]友好城市
题意: 这题显然直接tarjan是做不了的. 这里安利另一个求SCC的算法Kosaraju,学习的话可以见这篇博客 于是结合莫队,我们有了个暴力. 发现主要瓶颈是dfs过程中找最小的未经过的点,我们用 ...
- 【BZOJ 5222】[Lydsy2017省队十连测]怪题
题目大意: 传送门 给一个长度为$n(n<=200)$的数列$h$,再给$m$个可以无限使用的操作,第$i$个操作为给长度为花费$c_i$的价值给长度为$l_i$的数列子序列+1或-1,求将数列 ...
- bzoj 5217: [Lydsy2017省队十连测]航海舰队
Description Byteasar 组建了一支舰队!他们现在正在海洋上航行着.海洋可以抽象成一张n×m 的网格图,其中有些位置是" .",表示这一格是海水,可以通过:有些位置 ...
随机推荐
- JavaScript 相关知识
一.数组 var a = [1,2,3,4]; console.log(a.length); a.push(5); console.log(a); // [1, 2, 3, 4, 5] var r ...
- ruby:TypeError: 对象不支持此属性或方法
解决办法. 1.下载对应版本 下载node.js,根据ruby版本决定下载32还是x64,我的ruby版本x64 https://npm.taobao.org/mirrors/node/v8.9.3/ ...
- Linux基础常用命令
Linux 下命令有很多,并且很多命令用法又有不同的选项,这里介绍一些常用的最基本的Linux命令的用法,希望给大家留下便利之处. 1.cd 切换目录.例如 cd /home 可切换到home目录, ...
- Python format 格式化函数
str.format() 格式化字符串的函数 str.format(),它增强了字符串格式化的功能. 基本语法是通过 {} 和 : 来代替以前的 % format 函数可以接受不限个参数,位置可以不按 ...
- PHP截取日期
date( 'Y-m-d ',strtotime('2017-10-9 12:23:35')) 通过时间格式,获取的是2017-10-9
- 深入理解PHP之require/include顺序
深入理解PHP之require/include顺序 作者: Laruence( ) 本文地址: http://www.laruence.com/2010/05/04/1450.html 转载请注明 ...
- Hey,man,are you ok? -- 关于心跳、故障监测、lease机制
电话之于短信.微信的一个很大的不同点在于,前者更加及时,有更快速直接的反馈:而后面两个虽然称之为instant message,但经常时发出去了就得等对方回复,等多久是不确定的.打电话能明确知道对方在 ...
- Ansible自动化运维工具-上
[Ansible特点] 1)Ansible与saltstack均是基于Python语言开发的 2)安装使用简单,基于不同插件和模块实现各种软件,平台,版本的管理以及支持虚拟容器多层级的部署 3)不需要 ...
- MSIL实用指南-生成if...else...语句
if...else...语句是非常重要的选择语句,它的生成一般需要ILGenerator的DefineLabel方法和MarkLabel方法,以及Brtrue_S和Br_S指令. 一.DefineLa ...
- 开源软件:NoSql数据库 - 图数据库 Cassandra
转载原文:http://www.cnblogs.com/loveis715/p/5299495.html Cassandra简介 在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了 ...