一开始读错题,各种不会做,后来发现染色只是染孩子……

那不就简单了吗……注意这题是允许离线的

染色如果没有距离限制,它就是个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的更多相关文章

  1. 【kd-tree】bzoj4154 [Ipsc2015]Generating Synergy

    区间修改的kd-tree,打标记,下传. 每次询问的时候,从询问点向上找到根,然后依次下传下来,再回答询问. #include<cstdio> #include<algorithm& ...

  2. 【BZOJ4154】[Ipsc2015]Generating Synergy KDtree

    [BZOJ4154][Ipsc2015]Generating Synergy Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问 ...

  3. [bzoj4154][Ipsc2015]Generating Synergy_KD-Tree_dfs序

    Generating Synergy bzoj-4154 Ipsc-2015 题目大意:给定一棵n个节点树,m个操作,支持:将一个点周围所有距该点距离不超过l的子结点的颜色改成另一种颜色:查询单点颜色 ...

  4. BZOJ4154: [Ipsc2015]Generating Synergy

    Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色   Input 第一行一个数T,表示数据组数 接下来每组数据的第一 ...

  5. BZOJ4154:[Ipsc2015]Generating Synergy(K-D Tree)

    Description 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 Input 第一行一个数T,表示数据组数 接下来每组数据的第一行三 ...

  6. 【BZOJ4154】Generating Synergy【kd树】

    题意 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 分析 我们以dfs序为横坐标,深度为纵坐标,建kd树.我们每次更新,都是在kd树中更 ...

  7. BZOJ4154:[IPSC2015]Generating Synergy

    浅谈\(K-D\) \(Tree\):https://www.cnblogs.com/AKMer/p/10387266.html 题目传送门:https://lydsy.com/JudgeOnline ...

  8. 【bzoj4154】[Ipsc2015]Generating Synergy KD-tree

    题目描述 给定一棵以1为根的有根树,初始所有节点颜色为1,每次将距离节点a不超过l的a的子节点染成c,或询问点a的颜色 输入 第一行一个数T,表示数据组数 接下来每组数据的第一行三个数n,c,q表示结 ...

  9. 【bzoj4154】(dfs序+kd-tree)

    传送门 题意: 给出一颗以\(1\)为根的有根树,初始所有结点的颜色为\(1\). 之后有两个操作,一种是每次将距离\(a\)结点距离不超过\(l\)的所有儿子结点颜色染为\(c\):另一种是询问结点 ...

随机推荐

  1. Swift和OC,是编译型语言、解释性语言、运行时语言

    首先需要明确的一点是,什么是编译型语言和解释性语言 编译型语言,就是在其执行过程中需要先将其经过编译成机器码来给计算机识别的,其执行效率就会比较高这个是显而易见的,常见比如:C.C++ 而解释型语言, ...

  2. 《C++Primer》复习——with C++11 [2]

    1.数组引用形参,C++允许将变量定义成数组的引用,给予同样的道理,形参也可以是数组的引用,此时引用形参绑定到对应的实参上,也就是绑定到数组上 ]) { for (auto elem : arr) c ...

  3. sqlserver 2008 卸载时提示 “重新启动计算机”失败

    问题:sqlserver 2008 卸载时提示 “重新启动计算机”失败 解决办法: 1.打开注册表:开始->运行: regedit 2.找到HKEY_LOCAL_MACHINE\SYSTEM\C ...

  4. 使用Putty连接VirtualBox的Ubuntu

    从vbox中安装了ubuntu server,然后用ssh连过去,发现有一个错误:server unexpectedly closed network connection.猛然发现,ssh没有安装. ...

  5. mysql数据库连接池 手动编写

    源码来源于http://www.toutiao.com/a6350448676050174209/,留存以供以后参考学习 先上一张项目托普图 然后分别列出各个文件的源码: MyPool.java(就是 ...

  6. git撤销删除

    问题描述:     使用git时本地文件删除了,提交至github,希望撤销修改,找回源文件 问题解决: (1)查看git log,查看日志信息 注:     使用 git log 可以查看提交的日志 ...

  7. java.lang.NullPointerException&com.cb.action.LoginAction.execute(LoginAction.java:48)

    今天做一个Spring和Struts的融合,通过bean注入后,程序一跑起来,就报这个错误: java.lang.NullPointerException com.cb.action.LoginAct ...

  8. jQuery中的&& ||

    jQuery1.2.6 clean方法中有这么一段第一眼看去会让人晕掉的方法.完全不知其所言. “||, && 可以这样用?”,“这段东西最终返回的是个什么对象啊?” // Trim ...

  9. Git 使用方法

    Git 常用命令 git init here -- 创建本地仓库(repository),将会在文件夹下创建一个 .git 文件夹,.git 文件夹里存储了所有的版本信息.标记等内容 git remo ...

  10. 各种实用的js,bootstrap插件

    1.nivoSlider  非常优秀的Banner轮播插件 2.BootstrapTable 表格插件使用技巧 = http://www.cnblogs.com/landeanfen/p/497683 ...