bzoj4154
一开始读错题,各种不会做,后来发现染色只是染孩子……
那不就简单了吗……注意这题是允许离线的
染色如果没有距离限制,它就是个dfs序
距离限制怎么做呢?我们考虑扩展一维变成二维的问题,将每个点变为二维平面上的点(x,y),y=d[x]表示x的深度
染色a,距离限制l实际上就是对x∈[l,r],y<=d[a]+l的二维点染色([l,r]表示dfs序对应的区间)
这是一个非常经典的思路,我们可以扩展一维方便表示限制
注意染色的贡献是独立的,考虑离线的cdq分治,对于所有操作,我们把l变成d[a]+l;
然后以l为关键字降序排序,然后对时间线分治,设cdq(l,r)表示解决的第[l,r]的所有操作
考虑时间线[l,m]的染色操作对[m+1,r]的查询操作的影响,我们已经按l为关键字排序了,
对询问点产生影响的一定是区间包含这个点的最后一次操作,因此我们维护以时间为关键字的线段树
这样就是维护最大值,区间覆盖,单点查询,用线段树即可
然后递归下去处理即可
const mo=;
type node=record
l,c,a:longint;
end;
way=record
po,next:longint;
end; var a:array[..] of node;
e:array[..] of way;
v:array[..*] of boolean;
ans,fa,d,ld,rd,p,q,tq:array[..] of longint;
tag,st:array[..*] of longint;
tot,k,i,n,m,tt,t,x,y,len:longint;
s:int64; procedure add(x,y:longint);
begin
inc(len);
e[len].po:=y;
e[len].next:=p[x];
p[x]:=len;
end; procedure dfs(x:longint);
var i,y:longint;
begin
inc(t);
ld[x]:=t;
i:=p[x];
while i<> do
begin
y:=e[i].po;
d[y]:=d[x]+;
dfs(y);
i:=e[i].next;
end;
rd[x]:=t;
end; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; function cmp(i,j:longint):boolean;
begin
if a[i].l=a[j].l then exit(a[i].c>a[j].c);
exit(a[i].l>a[j].l);
end; procedure sort(l,r:longint);
var i,j,x:longint;
begin
i:=l;
j:=r;
x:=q[(l+r) shr ];
repeat
while cmp(q[i],x) do inc(i);
while cmp(x,q[j]) do dec(j);
if not(i>j) then
begin
swap(q[i],q[j]);
inc(i);
dec(j);
end;
until i>j;
if l<j then sort(l,j);
if i<r then sort(i,r);
end; procedure deal(i,x:longint);
begin
if (tag[i]<x) then tag[i]:=x;
if not v[i] then
begin
inc(tot);
st[tot]:=i;
v[i]:=true;
end;
end; procedure push(i:longint);
begin
if tag[i]<> then
begin
deal(i*,tag[i]);
deal(i*+,tag[i]);
tag[i]:=;
end;
end; procedure work(i,l,r,x,y,z:longint);
var m:longint;
begin
if (x<=l) and (y>=r) then
deal(i,z)
else begin
m:=(l+r) shr ;
push(i);
if x<=m then work(i*,l,m,x,y,z);
if y>m then work(i*+,m+,r,x,y,z);
end;
end; function ask(i,l,r,x:longint):longint;
var m:longint;
begin
if (l=r) then exit(tag[i])
else begin
m:=(l+r) shr ;
push(i);
if x<=m then exit(ask(i*,l,m,x))
else exit(ask(i*+,m+,r,x));
end;
end; procedure cdq(l,r:longint);
var i,t,x,f1,f2,h:longint;
begin
if l=r then exit;
m:=(l+r) shr ;
t:=;
tot:=;
h:=;
for i:=l to r do
begin
if (q[i]<=m) and (a[q[i]].c<>) or (q[i]>m) and (a[q[i]].c=) then
begin
inc(t);
tq[t]:=q[i];
end;
if q[i]<=m then inc(h);
end;
for i:= to t do
begin
x:=tq[i];
if a[x].c= then
begin
f1:=ask(,,n,ld[a[x].a]);
if f1> then ans[x]:=a[f1].c;
end
else work(,,n,ld[a[x].a],rd[a[x].a],x);
end;
for i:= to tot do
begin
tag[st[i]]:=;
v[st[i]]:=false;
end;
f1:=l;
f2:=l+h;
for i:=l to r do
if q[i]<=m then
begin
tq[f1]:=q[i];
inc(f1);
end
else begin
tq[f2]:=q[i];
inc(f2);
end;
for i:=l to r do
q[i]:=tq[i];
cdq(l,f1-);
cdq(f1,r);
end; begin
readln(tt);
while tt> do
begin
dec(tt);
fillchar(p,sizeof(p),);
readln(n,m,k);
len:=;
for i:= to n do
begin
read(fa[i]);
add(fa[i],i);
end;
t:=;
dfs();
for i:= to k do
begin
readln(a[i].a,a[i].l,a[i].c);
if a[i].c<> then
begin
a[i].l:=a[i].l+d[a[i].a];
ans[i]:=;
end
else begin
a[i].l:=d[a[i].a];
ans[i]:=;
end;
q[i]:=i;
end;
sort(,k);
cdq(,k);
s:=;
for i:= to k do
s:=(s+int64(ans[i])*int64(i)) mod mo;
writeln(s);
end;
end.
bzoj4154的更多相关文章
- 【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy
区间修改的kd-tree,打标记,下传. 每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问. #include<cstdio> #include<algorithm& ...
- 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree
[BZOJ4154][Ipsc2015]Generating Synergy Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问 ...
- [bzoj4154][Ipsc2015]Generating Synergy_KD-Tree_dfs序
Generating Synergy bzoj-4154 Ipsc-2015 题目大意:给定一棵n个节点树,m个操作,支持:将一个点周围所有距该点距离不超过l的子结点的颜色改成另一种颜色:查询单点颜色 ...
- BZOJ4154: [Ipsc2015]Generating Synergy
Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 Input 第一行一个数T,表示数据组数 接下来每组数据的第一 ...
- BZOJ4154:[Ipsc2015]Generating Synergy(K-D Tree)
Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 Input 第一行一个数T,表示数据组数 接下来每组数据的第一行三 ...
- 【BZOJ4154】Generating Synergy【kd树】
题意 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 分析 我们以dfs序为横坐标,深度为纵坐标,建kd树.我们每次更新,都是在kd树中更 ...
- BZOJ4154:[IPSC2015]Generating Synergy
浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...
- 【bzoj4154】[Ipsc2015]Generating Synergy KD-tree
题目描述 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 输入 第一行一个数T,表示数据组数 接下来每组数据的第一行三个数n,c,q表示结 ...
- 【bzoj4154】(dfs序+kd-tree)
传送门 题意: 给出一颗以\(1\)为根的有根树,初始所有结点的颜色为\(1\). 之后有两个操作,一种是每次将距离\(a\)结点距离不超过\(l\)的所有儿子结点颜色染为\(c\):另一种是询问结点 ...
随机推荐
- Ubuntu 下为 Idea 创建启动图标.
默认情况下,ubuntu将自动安装的软件快捷方式保存在/usr/share/applications目录下,如果我们要创建桌面快捷方式,需要在该目录下创建一个名为“Idea.desktop”的文件.通 ...
- ios状态栏调整 简单动画的知识点
首先状态栏式view的属性,所以在viewController中直接重写: /** 修改状态栏 */ - (UIStatusBarStyle)preferredStatusBarStyle { // ...
- 【读书笔记】Redis入门
1:Redis概览 Remote Dictionary Server 远程字典服务 Redis是基于内存的存储 在一台普通的笔记本上,Redis每秒的读取速度可以达到10万 内存读取数据,断电的时候数 ...
- protocol buffer 整数序列化
http://blog.csdn.net/csfreebird/article/details/7624807 varints用于正整数 (无符号整数) varints 是 一个很不错的技术.将一个整 ...
- zabbix3.0 安装方法,一键实现短信、电话、微信、APP 告警
引言 免费开源监控工具 Zabbix 因其强大的监控功能得到各大互联网公司的广泛认可,具体功能不再详细介绍,在之前发布的 Zabbix 2.4.1 安装及微信短信提醒已经做了详细介绍,本篇主要对 Za ...
- 深入理解Tornado——一个异步web服务器
本人的第一次翻译,转载请注明出处:http://www.cnblogs.com/yiwenshengmei/archive/2011/06/08/understanding_tornado.html原 ...
- POJ 1701
/* Every tenant went up N floors would make the dissatisfied degree rise N * a + 0.5 * N * (N - 1) d ...
- Winform基础 -- 菜单
快速创建默认菜单 使用控件 MenuStrip : 点击菜单的右上方小三角:选择 [插入标准项] 即可显现出标准的菜单格式: 如果想添加更多的菜单项,可以在 [请在此处键入] 处输入菜单项的名称 ...
- lintcode: 二叉查找树中搜索区间
题目 二叉查找树中搜索区间 给定两个值 k1 和 k2(k1 < k2)和一个二叉查找树的根节点.找到树中所有值在 k1 到 k2 范围内的节点.即打印所有x (k1 <= x <= ...
- [z]CAP原理和BASE思想
分布式领域CAP理论,Consistency(一致性), 数据一致更新,所有数据变动都是同步的Availability(可用性), 好的响应性能Partition tolerance(分区容错性) 可 ...