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

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

染色如果没有距离限制,它就是个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. 高德开发 android 出现 key 鉴权失败

    环境windows + android studio 原因: 曾经更改过key.store 解决办法: 首先运行cmd移动到keystore的目录下keytool -list -keystore 文件 ...

  2. Start my cnBlogs

    Compared to CSDN blog, althought it's my first time to use CNBlog,i felt it makes me more comfortabl ...

  3. SqlBulkCopy批量写入25万条数据只需3s

    Microsoft SQL Server 提供一个称为 bcp 的流行的命令提示符实用工具,用于将数据从一个表移动到另一个表(表既可以在同一个服务器上,也可以在不同服务器上).SqlBulkCopy  ...

  4. ios Camera学习笔记

    检测设备的摄像头是否可用: - (BOOL) isCameraAvailable{ return [UIImagePickerController isSourceTypeAvailable: UII ...

  5. 【BZOJ】【1391】【CEOI2008】order

    网络流/最小割 暴力建图就好了……S->i 容量为收益,i->j+n 容量为租金,j+n->T容量为购买所花的钱. 如果亏钱的话那么割掉的就是收益,表示不赚钱. 如果租金大于购买所花 ...

  6. [转载]DateTime TryParse

    今天被Architect问住了,说你光用一个TryParse就判断人家是不是时间日期型的,是不完整的.所以我花点时间看了下TryParse的用法. MSDN:http://msdn.microsoft ...

  7. PHP开发框架[流行度排名]

    在PHP开发中,选择合适的框架有助于加快软件开发,节约宝贵的项目时间,让开发者专注于功能的实现上.Sitepoint网站做了一个小的调查,结果显示最流行的PHP框架前三甲为:Laravel.Phalc ...

  8. 【DDD-Apwork框架】事件总线和事件聚合器

    第一步:事件总线和事件聚合器 [1]事件总线 IEventBus IUnitOfWork.cs using System; using System.Collections.Generic; usin ...

  9. 【QT】计时器制作

    应小伙伴的要求,做一个小计时器.功能是点击开始就从00:00:00开始计时,点击暂停就暂停计时,点击停止就停止计时. 界面如上图,使用ui设计师直接拖的.按钮和图标的图片都是网上下载的.用美图秀秀抠成 ...

  10. 重写equals()方法时,需要同时重写hashCode()方法

    package com.wangzhu.map; import java.util.HashMap; /** * hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,<br/&g ...