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\):另一种是询问结点 ...
随机推荐
- Interview-Largest independent set in binary tree.
BT(binary tree), want to find the LIS(largest independent set) of the BT. LIS: if the current node i ...
- Ffmpeg 定位文件(seek file)
有朋友问到ffmpeg播放文件如何定位问题,我想到应该还有一些新手朋友对这一块比较陌生.ffmpeg定位问题用到seek方法,代码 如下: void SeekFrame(AVFormatContext ...
- POJ 3553 Task schedule
原题链接:http://poj.org/problem?id=3553 这道题主要就是贪心思想吧,对于每个job,根据其截止时间 dj 从小到大排序,我们必须要尽快把dj最小的job完成掉,这样才能使 ...
- 2014 Multi-University Training Contest 6
官方解题报告:http://blog.sina.com.cn/s/blog_a19ad7a10102uz2v.html Apple Tree http://acm.hdu.edu.cn/showpro ...
- C#动态多线程实例
在C#中用多线程并不难实现.它有一个命名空间:System.Threading,提供了多线程的支持. 要开启一个新线程,须要以下的初始化: ThreadStart startDownload = ne ...
- [转载]C#如何在webBrowser1控件通过TagName,Name查找元素(没有ID时)遍历窗体元素
//防止页面多次刷新页面执行 ) { string GetUserName = System.Configuration.ConfigurationSettings.AppSettings[" ...
- Linux GPT分区
parted /dev/sdb //parted sdb磁盘 mklabel gpt //设置该磁盘分区为gpt mkpart primary 0% 100% //划分分区大 ...
- uva 991
卡特兰数 最后不输出空行... #include <cstdio> #include <cstdlib> #include <cmath> #include &l ...
- wordpress数据库优化-关闭日志修订
每次在wordpress网站修改文章的时候都会产生一个修订版本,wp_posts会产生一个post_type为“REVISIONS”的记录,修改次数一多的话,那修订版本就有几万条记录了 在functi ...
- httpClient无证书访问
1.当不需要使用任何证书访问https网页时,只需配置信任任何证书 HttpClient http = new HttpClient(); String url = "https://pay ...