标签:
这是一道神题,首先我们不难先到整体二分吧
下面的问题就是,求出对于每个水果,有多少盘子是他的子路径
直接考虑不是很容易,我们换个思路,考虑对于每个盘子,哪些水果能包含它
我们假设盘子a,b,dep[a]<dep[b]
如果b在a的子树内,不难发现,水果路径必须是一个点在b的子树内(包括b),一个在c的子树外(不包括c,c是ab路径上a下一个点)
否则 ,水果路径必须两个点分别在a,b子树内
子树问题不难想到dfs序,设子树x区间为l[x],r[x],盘子路径x,y(l[x]<l[y])满足条件为
则要满足x∈[1,l[c]-1],y∈[l[b],r[b]或x∈[l[b],r[b]], y∈[l[c]+1,n] 当b在a的子树内
否则x∈[l[a],r[a]],y∈[l[b],r[b],把(x,y)看做一个点
也就是现在询问每个点被多少矩形覆盖(注意第一种情形两个矩形是不相交的,所以覆盖的矩形数目就是盘子数目
矩形覆盖的经典做法是吧矩形(x0,y0),(x1,y1)看成4个带权值的点
(x0,y0) 1, (x0,y1+1) -1, (x1+1,y0) -1 (x1+1,y1+1) 1,
这样每个询问点最下方(包括边界)的点权值和就是覆盖询问点的矩形数目(画图可知)
而这个问题我们对一维排序,一维树状数组即可快速解决
1 type node=record 2 po,next:longint; 3 end; 4 point=record 5 x,y,id,z:longint; 6 end; 7 8 var e:array[0..80010] of node; 9 dep,ans,st,a,b,c,p,d:array[0..50010] of longint; 10 anc:array[0..40010,0..18] of longint; 11 q,w,tw:array[0..400010] of point; 12 can,v:array[0..80010] of boolean; 13 j,tot,t,x,y,z,i,len,n,m,k,xx:longint; 14 15 function lowbit(x:longint):longint; 16 begin 17 exit(x and (-x)); 18 end; 19 20 procedure swap(var a,b:longint); 21 var c:longint; 22 begin 23 c:=a; 24 a:=b; 25 b:=c; 26 end; 27 28 procedure add(x,y:longint); 29 begin 30 inc(len); 31 e[len].po:=y; 32 e[len].next:=p[x]; 33 p[x]:=len; 34 end; 35 36 procedure dfs(x:longint); 37 var i,y:longint; 38 begin 39 inc(t); 40 a[x]:=t; 41 i:=p[x]; 42 while i<>0 do 43 begin 44 y:=e[i].po; 45 if a[y]=0 then 46 begin 47 anc[y,0]:=x; 48 dep[y]:=dep[x]+1; 49 dfs(y); 50 end; 51 i:=e[i].next; 52 end; 53 b[x]:=t; 54 end; 55 56 function jump(x,d:longint):longint; 57 var i:longint; 58 begin 59 for i:=16 downto 0 do 60 if dep[x]-1 shl i>=d then x:=anc[x,i]; 61 exit(x); 62 end; 63 64 function cmp(a,b:point):boolean; 65 begin 66 exit((a.x<b.x) or (a.x=b.x) and (a.y<b.y)); 67 end; 68 69 procedure sortc(l,r:longint); 70 var i,j,x:longint; 71 begin 72 i:=l; 73 j:=r; 74 x:=c[(l+r) shr 1]; 75 repeat 76 while c[i]<x do inc(i); 77 while x<c[j] do dec(j); 78 if not(i>j) then 79 begin 80 swap(c[i],c[j]); 81 inc(i); 82 dec(j); 83 end; 84 until i>j; 85 if l<j then sortc(l,j); 86 if i<r then sortc(i,r); 87 end; 88 89 procedure sortw(l,r:longint); 90 var i,j:longint; 91 x,y:point; 92 begin 93 i:=l; 94 j:=r; 95 x:=w[(l+r) shr 1]; 96 repeat 97 while cmp(w[i],x) do inc(i); 98 while cmp(x,w[j]) do dec(j); 99 if not(i>j) then 100 begin 101 y:=w[i]; w[i]:=w[j]; w[j]:=y; 102 inc(i); 103 dec(j); 104 end; 105 until i>j; 106 if l<j then sortw(l,j); 107 if i<r then sortw(i,r); 108 end; 109 110 procedure sortq(l,r:longint); 111 var i,j:longint; 112 x,y:point; 113 begin 114 i:=l; 115 j:=r; 116 x:=q[(l+r) shr 1]; 117 repeat 118 while cmp(q[i],x) do inc(i); 119 while cmp(x,q[j]) do dec(j); 120 if not(i>j) then 121 begin 122 y:=q[i]; q[i]:=q[j]; q[j]:=y; 123 inc(i); 124 dec(j); 125 end; 126 until i>j; 127 if l<j then sortq(l,j); 128 if i<r then sortq(i,r); 129 end; 130 131 procedure open(x0,x1,y0,y1,z:longint); 132 begin 133 inc(x1); inc(y1); 134 inc(t); w[t].x:=x0; w[t].y:=y0; w[t].id:=1; w[t].z:=z; 135 inc(t); w[t].x:=x0; w[t].y:=y1; w[t].id:=-1; w[t].z:=z; 136 inc(t); w[t].x:=x1; w[t].y:=y0; w[t].id:=-1; w[t].z:=z; 137 inc(t); w[t].x:=x1; w[t].y:=y1; w[t].id:=1; w[t].z:=z; 138 end; 139 140 procedure work(x,w:longint); 141 begin 142 while x<=n+1 do 143 begin 144 if not v[x] then 145 begin 146 v[x]:=true; 147 inc(tot); 148 st[tot]:=x; 149 end; 150 d[x]:=d[x]+w; 151 x:=x+lowbit(x); 152 end; 153 end; 154 155 function ask(x:longint):longint; 156 begin 157 ask:=0; 158 while x>0 do 159 begin 160 ask:=ask+d[x]; 161 x:=x-lowbit(x); 162 end; 163 end; 164 165 procedure cdq(opx,opy,qx,qy,l,r:longint); 166 var m,t,i,j,s,f1,f2,z,q1,q2:longint; 167 begin 168 if (l>r) or (qx>qy) then exit; 169 if l=r then 170 begin 171 for i:=qx to qy do 172 ans[q[i].id]:=c[l]; 173 exit; 174 end; 175 m:=(l+r) shr 1; //二分答案 176 t:=0; 177 for i:=opx to opy do 178 if w[i].z<=c[m] then 179 begin 180 inc(t); 181 tw[t]:=w[i]; 182 end; 183 184 z:=0; 185 j:=1; 186 for i:=qx to qy do 187 begin 188 can[i]:=false; 189 while (j<=t) and (tw[j].x<=q[i].x) do //扫描询问 190 begin 191 work(tw[j].y,tw[j].id); 192 inc(j); 193 end; 194 s:=ask(q[i].y); 195 if s>=q[i].z then 196 begin 197 ans[q[i].id]:=c[m]; 198 inc(z); 199 can[i]:=true; 200 end 201 else q[i].z:=q[i].z-s; 202 end; 203 f1:=opx-1; f2:=opx+t-1; //划分操作区间 204 for i:=opx to opy do 205 if w[i].z<=c[m] then 206 begin 207 inc(f1); 208 tw[f1]:=w[i]; 209 end 210 else begin 211 inc(f2); 212 tw[f2]:=w[i]; 213 end; 214 for i:=opx to opy do 215 w[i]:=tw[i]; 216 q1:=qx-1; q2:=qx+z-1; 217 for i:=qx to qy do 218 if can[i] then 219 begin 220 inc(q1); 221 tw[q1]:=q[i]; 222 end 223 else begin 224 inc(q2); 225 tw[q2]:=q[i]; 226 end; 227 for i:=qx to qy do 228 q[i]:=tw[i]; 229 for i:=1 to tot do 230 begin 231 s:=st[i]; 232 v[s]:=false; 233 d[s]:=0; 234 end; 235 tot:=0; 236 cdq(opx,f1,qx,q1,l,m); 237 cdq(f1+1,opy,q1+1,qy,m+1,r); 238 end; 239 240 begin 241 readln(n,m,k); 242 for i:=1 to n-1 do 243 begin 244 readln(x,y); 245 add(x,y); 246 add(y,x); 247 end; 248 dfs(1); 249 for j:=1 to trunc(ln(n)/ln(2))+1 do 250 for i:=1 to n do 251 begin 252 x:=anc[i,j-1]; 253 anc[i,j]:=anc[x,j-1]; 254 end; 255 256 t:=0; 257 for i:=1 to m do 258 begin 259 readln(x,y,z); 260 if a[x]>a[y] then swap(x,y); 261 if a[y]<=b[x] then 262 begin 263 xx:=jump(y,dep[x]+1); 264 if a[xx]<>1 then open(1,a[xx]-1,a[y],b[y],z); 265 if b[xx]<n then open(a[y],b[y],b[xx]+1,n,z); 266 end 267 else open(a[x],b[x],a[y],b[y],z); 268 c[i]:=z; 269 end; 270 sortc(1,m); 271 sortw(1,t); 272 for i:=1 to k do 273 begin 274 readln(x,y,z); 275 if a[x]>a[y] then swap(x,y); 276 q[i].x:=a[x]; q[i].y:=a[y]; q[i].id:=i; q[i].z:=z; 277 end; 278 sortq(1,k); 279 cdq(1,t,1,k,1,m); 280 for i:=1 to k do 281 writeln(ans[i]); 282 end.
标签:
原文地址:http://www.cnblogs.com/phile/p/4490782.html