bzoj4154
2015-06-30 10:14
120 查看
一开始读错题,各种不会做,后来发现染色只是染孩子……
那不就简单了吗……注意这题是允许离线的
染色如果没有距离限制,它就是个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为关键字排序了,
对询问点产生影响的一定是区间包含这个点的最后一次操作,因此我们维护以时间为关键字的线段树
这样就是维护最大值,区间覆盖,单点查询,用线段树即可
然后递归下去处理即可
View Code
那不就简单了吗……注意这题是允许离线的
染色如果没有距离限制,它就是个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=1000000007; type node=record l,c,a:longint; end; way=record po,next:longint; end; var a:array[0..100010] of node; e:array[0..100010] of way; v:array[0..100010*4] of boolean; ans,fa,d,ld,rd,p,q,tq:array[0..100010] of longint; tag,st:array[0..100010*4] 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<>0 do begin y:=e[i].po; d[y]:=d[x]+1; 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 1]; 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]<>0 then begin deal(i*2,tag[i]); deal(i*2+1,tag[i]); tag[i]:=0; 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 1; push(i); if x<=m then work(i*2,l,m,x,y,z); if y>m then work(i*2+1,m+1,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 1; push(i); if x<=m then exit(ask(i*2,l,m,x)) else exit(ask(i*2+1,m+1,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 1; t:=0; tot:=0; h:=0; for i:=l to r do begin if (q[i]<=m) and (a[q[i]].c<>0) or (q[i]>m) and (a[q[i]].c=0) then begin inc(t); tq[t]:=q[i]; end; if q[i]<=m then inc(h); end; for i:=1 to t do begin x:=tq[i]; if a[x].c=0 then begin f1:=ask(1,1,n,ld[a[x].a]); if f1>0 then ans[x]:=a[f1].c; end else work(1,1,n,ld[a[x].a],rd[a[x].a],x); end; for i:=1 to tot do begin tag[st[i]]:=0; 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-1); cdq(f1,r); end; begin readln(tt); while tt>0 do begin dec(tt); fillchar(p,sizeof(p),0); readln(n,m,k); len:=0; for i:=2 to n do begin read(fa[i]); add(fa[i],i); end; t:=0; dfs(1); for i:=1 to k do begin readln(a[i].a,a[i].l,a[i].c); if a[i].c<>0 then begin a[i].l:=a[i].l+d[a[i].a]; ans[i]:=0; end else begin a[i].l:=d[a[i].a]; ans[i]:=1; end; q[i]:=i; end; sort(1,k); cdq(1,k); s:=0; for i:=1 to k do s:=(s+int64(ans[i])*int64(i)) mod mo; writeln(s); end; end.
View Code
相关文章推荐
- 有用的oracle语句
- App Store被拒理由大全
- UNIX环境高级编程(第16章 网络IPC:套接字)
- 第16周周五 随机数的使用
- 敏捷开发概念
- make clean、 make mrproper、make distclean的区别 .
- LeetCode150 Evaluate Reverse Polish Notation java题解
- Source RPMs for Broadcom drivers
- 其五 关于构造器
- 钥匙串(Keychain)服务编程指南-iOS部分
- C++ Custom Control控件向父窗体发送对应的消息
- Linux中断(interrupt)子系统之二:arch相关的硬件封装层
- android 适配器的使用
- Java实现读取文件夹下(包括子目录)所有文件的文件名
- UNIX环境高级编程(第15章 进程间通信)
- SQLServer获取随机数据
- iOS 得到系统的IP地址
- php生成CSV文件
- THUSC2015
- 编写一个学生和教师数据输入和显示程序,学生数据有编号,姓名,班号,和成绩,教师数据有编号,姓名,职称和部门。要求将编号,姓名输入显示设计成一个类person,并作为学生数据类t和教师数据操作类的基类