一开始读错题,各种不会做,后来发现染色只是染孩子……
那不就简单了吗……注意这题是允许离线的
染色如果没有距离限制,它就是个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为关键字排序了,
对询问点产生影响的一定是区间包含这个点的最后一次操作,因此我们维护以时间为关键字的线段树
这样就是维护最大值,区间覆盖,单点查询,用线段树即可
然后递归下去处理即可
1 const mo=1000000007; 2 type node=record 3 l,c,a:longint; 4 end; 5 way=record 6 po,next:longint; 7 end; 8 9 var a:array[0..100010] of node; 10 e:array[0..100010] of way; 11 v:array[0..100010*4] of boolean; 12 ans,fa,d,ld,rd,p,q,tq:array[0..100010] of longint; 13 tag,st:array[0..100010*4] of longint; 14 tot,k,i,n,m,tt,t,x,y,len:longint; 15 s:int64; 16 17 procedure add(x,y:longint); 18 begin 19 inc(len); 20 e[len].po:=y; 21 e[len].next:=p[x]; 22 p[x]:=len; 23 end; 24 25 procedure dfs(x:longint); 26 var i,y:longint; 27 begin 28 inc(t); 29 ld[x]:=t; 30 i:=p[x]; 31 while i<>0 do 32 begin 33 y:=e[i].po; 34 d[y]:=d[x]+1; 35 dfs(y); 36 i:=e[i].next; 37 end; 38 rd[x]:=t; 39 end; 40 41 procedure swap(var a,b:longint); 42 var c:longint; 43 begin 44 c:=a; 45 a:=b; 46 b:=c; 47 end; 48 49 function cmp(i,j:longint):boolean; 50 begin 51 if a[i].l=a[j].l then exit(a[i].c>a[j].c); 52 exit(a[i].l>a[j].l); 53 end; 54 55 procedure sort(l,r:longint); 56 var i,j,x:longint; 57 begin 58 i:=l; 59 j:=r; 60 x:=q[(l+r) shr 1]; 61 repeat 62 while cmp(q[i],x) do inc(i); 63 while cmp(x,q[j]) do dec(j); 64 if not(i>j) then 65 begin 66 swap(q[i],q[j]); 67 inc(i); 68 dec(j); 69 end; 70 until i>j; 71 if l<j then sort(l,j); 72 if i<r then sort(i,r); 73 end; 74 75 procedure deal(i,x:longint); 76 begin 77 if (tag[i]<x) then tag[i]:=x; 78 if not v[i] then 79 begin 80 inc(tot); 81 st[tot]:=i; 82 v[i]:=true; 83 end; 84 end; 85 86 procedure push(i:longint); 87 begin 88 if tag[i]<>0 then 89 begin 90 deal(i*2,tag[i]); 91 deal(i*2+1,tag[i]); 92 tag[i]:=0; 93 end; 94 end; 95 96 procedure work(i,l,r,x,y,z:longint); 97 var m:longint; 98 begin 99 if (x<=l) and (y>=r) then 100 deal(i,z) 101 else begin 102 m:=(l+r) shr 1; 103 push(i); 104 if x<=m then work(i*2,l,m,x,y,z); 105 if y>m then work(i*2+1,m+1,r,x,y,z); 106 end; 107 end; 108 109 function ask(i,l,r,x:longint):longint; 110 var m:longint; 111 begin 112 if (l=r) then exit(tag[i]) 113 else begin 114 m:=(l+r) shr 1; 115 push(i); 116 if x<=m then exit(ask(i*2,l,m,x)) 117 else exit(ask(i*2+1,m+1,r,x)); 118 end; 119 end; 120 121 procedure cdq(l,r:longint); 122 var i,t,x,f1,f2,h:longint; 123 begin 124 if l=r then exit; 125 m:=(l+r) shr 1; 126 t:=0; 127 tot:=0; 128 h:=0; 129 for i:=l to r do 130 begin 131 if (q[i]<=m) and (a[q[i]].c<>0) or (q[i]>m) and (a[q[i]].c=0) then 132 begin 133 inc(t); 134 tq[t]:=q[i]; 135 end; 136 if q[i]<=m then inc(h); 137 end; 138 for i:=1 to t do 139 begin 140 x:=tq[i]; 141 if a[x].c=0 then 142 begin 143 f1:=ask(1,1,n,ld[a[x].a]); 144 if f1>0 then ans[x]:=a[f1].c; 145 end 146 else work(1,1,n,ld[a[x].a],rd[a[x].a],x); 147 end; 148 for i:=1 to tot do 149 begin 150 tag[st[i]]:=0; 151 v[st[i]]:=false; 152 end; 153 f1:=l; 154 f2:=l+h; 155 for i:=l to r do 156 if q[i]<=m then 157 begin 158 tq[f1]:=q[i]; 159 inc(f1); 160 end 161 else begin 162 tq[f2]:=q[i]; 163 inc(f2); 164 end; 165 for i:=l to r do 166 q[i]:=tq[i]; 167 cdq(l,f1-1); 168 cdq(f1,r); 169 end; 170 171 begin 172 readln(tt); 173 while tt>0 do 174 begin 175 dec(tt); 176 fillchar(p,sizeof(p),0); 177 readln(n,m,k); 178 len:=0; 179 for i:=2 to n do 180 begin 181 read(fa[i]); 182 add(fa[i],i); 183 end; 184 t:=0; 185 dfs(1); 186 for i:=1 to k do 187 begin 188 readln(a[i].a,a[i].l,a[i].c); 189 if a[i].c<>0 then 190 begin 191 a[i].l:=a[i].l+d[a[i].a]; 192 ans[i]:=0; 193 end 194 else begin 195 a[i].l:=d[a[i].a]; 196 ans[i]:=1; 197 end; 198 q[i]:=i; 199 end; 200 sort(1,k); 201 cdq(1,k); 202 s:=0; 203 for i:=1 to k do 204 s:=(s+int64(ans[i])*int64(i)) mod mo; 205 writeln(s); 206 end; 207 end.
时间: 2024-11-09 09:56:18