bzoj4012: [HNOI2015]开店
人生哲学。最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱。这样的
想法当然非常好啦,但是她们也发现她们面临着一个问题,那就是店开在哪里,面
向什么样的人群。很神奇的是,幻想乡的地图是一个树形结构,幻想乡一共有 n
个地方,编号为 1 到 n,被 n-1 条带权的边连接起来。每个地方都住着一个妖怪,
其中第 i 个地方的妖怪年龄是 x_i。妖怪都是些比较喜欢安静的家伙,所以它们并
不希望和很多妖怪相邻。所以这个树所有顶点的度数都小于或等于 3。妖怪和人一
样,兴趣点随着年龄的变化自然就会变化,比如我们的 18 岁少女幽香和八云紫就
比较喜欢可爱的东西。幽香通过研究发现,基本上妖怪的兴趣只跟年龄有关,所以
幽香打算选择一个地方 u(u为编号),然后在 u开一家面向年龄在 L到R 之间(即
年龄大于等于 L、小于等于 R)的妖怪的店。也有可能 u这个地方离这些妖怪比较
远,于是幽香就想要知道所有年龄在 L 到 R 之间的妖怪,到点 u 的距离的和是多
少(妖怪到 u 的距离是该妖怪所在地方到 u 的路径上的边的权之和) ,幽香把这个
称为这个开店方案的方便值。幽香她们还没有决定要把店开在哪里,八云紫倒是准
备了很多方案,于是幽香想要知道,对于每个方案,方便值是多少呢。
Input
第一行三个用空格分开的数 n、Q和A,表示树的大小、开店的方案个数和妖
怪的年龄上限。
第二行n个用空格分开的数 x_1、x_2、…、x_n,x_i 表示第i 个地点妖怪的年
龄,满足0<=x_i<A。(年龄是可以为 0的,例如刚出生的妖怪的年龄为 0。)
接下来 n-1 行,每行三个用空格分开的数 a、b、c,表示树上的顶点 a 和 b 之
间有一条权为c(1 <= c <= 1000)的边,a和b 是顶点编号。
接下来Q行,每行三个用空格分开的数 u、 a、 b。对于这 Q行的每一行,用 a、
b、A计算出 L和R,表示询问“在地方 u开店,面向妖怪的年龄区间为[L,R]的方
案的方便值是多少”。对于其中第 1 行,L 和 R 的计算方法为:L=min(a%A,b%A),
R=max(a%A,b%A)。对于第 2到第 Q行,假设前一行得到的方便值为 ans,那么当
前行的 L 和 R 计算方法为: L=min((a+ans)%A,(b+ans)%A),
R=max((a+ans)%A,(b+ans)%A)。
Output
对于每个方案,输出一行表示方便值。
Sample Input
10 10 10
0 0 7 2 1 4 7 7 7 9
1 2 270
2 3 217
1 4 326
2 5 361
4 6 116
3 7 38
1 8 800
6 9 210
7 10 278
8 9 8
2 8 0
9 3 1
8 0 8
4 2 7
9 7 3
4 7 0
2 2 7
3 2 1
2 3 4
0 0 7 2 1 4 7 7 7 9
1 2 270
2 3 217
1 4 326
2 5 361
4 6 116
3 7 38
1 8 800
6 9 210
7 10 278
8 9 8
2 8 0
9 3 1
8 0 8
4 2 7
9 7 3
4 7 0
2 2 7
3 2 1
2 3 4
Sample Output
1603
957
7161
9466
3232
5223
1879
1669
1282
0
957
7161
9466
3232
5223
1879
1669
1282
0
HINT
满足 n<=150000,Q<=200000。对于所有数据,满足 A<=10^9
题解
其实就是动态点分治的模板题……但是如果是动态点分套线段树的话看起来会mle,于是我们可以开个数组对于每个子树按权值从小到大记录在当前子树里点的信息(是的我知道你们c++有vector不用那么麻烦),然后算个前缀和在上面二分查找一减就行了……
其实还挺好写的……
1 program j01; 2 const maxn=300086; 3 var head:array[0..maxn]of longint; 4 data:array[0..2*maxn]of int64; 5 q,next:array[0..2*maxn]of longint; 6 size,now,maxu:array[0..maxn]of longint; 7 st:array[0..22,0..2*maxn]of longint; 8 fa:array[0..maxn]of longint; 9 dep:array[0..maxn]of int64; 10 sum1,sum2:array[0..20*maxn]of int64; 11 root,rosize,mnsize:longint; 12 fir:array[0..maxn]of longint; 13 vis:array[0..maxn]of boolean; 14 bin:array[0..2*maxn]of longint; 15 u,v,w,n,m,tt,aa,i,time,tot,j:longint; 16 a,ps:array[0..maxn]of longint; 17 line:array[0..20*maxn]of longint; 18 bg,ed:array[0..maxn]of longint; 19 ax,bx,ll,rr,ans:int64; 20 21 22 function max(a,b:int64):int64;inline;begin if a>b then exit(a) else exit(b);end; 23 function min(a,b:int64):int64;inline;begin if a<b then exit(a) else exit(b);end; 24 25 procedure swap(var a,b:longint); 26 var c:longint; 27 begin 28 c:=a;a:=b;b:=c; 29 end; 30 31 procedure addd(u,v,w:longint); 32 begin 33 inc(tt);q[tt]:=v;data[tt]:=w;next[tt]:=head[u];head[u]:=tt; 34 end; 35 36 procedure sort(l,r:longint); 37 var i,j,x,y:longint; 38 begin 39 i:=l;j:=r;x:=a[ps[(i+j)div 2]]; 40 repeat 41 while a[ps[i]]<x do inc(i); 42 while x<a[ps[j]] do dec(j); 43 if i<=j then 44 begin 45 swap(ps[i],ps[j]); 46 inc(i);dec(j); 47 end; 48 until i>j; 49 if i<r then sort(i,r); 50 if l<j then sort(l,j); 51 end; 52 53 procedure dfsst(i,pre:longint); 54 var j:longint; 55 begin 56 inc(time);fir[i]:=time;st[0,time]:=i; 57 j:=head[i]; 58 while j>0 do 59 begin 60 if q[j]<>pre then 61 begin 62 dep[q[j]]:=dep[i]+data[j];dfsst(q[j],i); 63 inc(time);st[0,time]:=i; 64 end; 65 j:=next[j]; 66 end; 67 end; 68 69 function min_st(a,b:longint):longint; 70 begin 71 if fir[a]<fir[b] then exit(a) else exit(b); 72 end; 73 74 procedure getst; 75 var i,j:longint; 76 begin 77 bin[1]:=0; 78 for i:=2 to time do 79 if i and(i-1)=0 then bin[i]:=bin[i-1]+1 else bin[i]:=bin[i-1]; 80 for i:=1 to bin[time] do 81 for j:=1 to time+1-(1 shl i) do 82 st[i,j]:=min_st(st[i-1,j],st[i-1,j+(1 shl(i-1))]); 83 end; 84 85 function lca(u,v:longint):longint; 86 var k:longint; 87 begin 88 u:=fir[u];v:=fir[v];if u>v then swap(u,v);k:=bin[v-u+1]; 89 exit(min_st(st[k,u],st[k,v+1-(1 shl k)])); 90 end; 91 92 function dist(u,v:longint):int64; 93 begin 94 exit(dep[u]+dep[v]-2*dep[lca(u,v)]); 95 end; 96 97 procedure dfssize(i,pre:longint); 98 var j:longint; 99 begin 100 size[i]:=1;maxu[i]:=0;j:=head[i]; 101 while j>0 do 102 begin 103 if(vis[q[j]]=false)and(q[j]<>pre)then 104 begin 105 dfssize(q[j],i);inc(size[i],size[q[j]]); 106 maxu[i]:=max(maxu[i],size[q[j]]); 107 end; 108 j:=next[j]; 109 end; 110 end; 111 112 procedure dfsroot(i,pre:longint); 113 var j:longint; 114 begin 115 maxu[i]:=max(maxu[i],rosize-size[i]); 116 if maxu[i]<mnsize then begin root:=i;mnsize:=maxu[i]; end; 117 j:=head[i]; 118 while j>0 do 119 begin 120 if(vis[q[j]]=false)and(q[j]<>pre)then dfsroot(q[j],i); 121 j:=next[j]; 122 end; 123 end; 124 125 procedure dfstree(i,pre:longint); 126 var j,ro:longint; 127 begin 128 dfssize(i,0);mnsize:=maxlongint;rosize:=size[i]; 129 dfsroot(i,0);ro:=root;now[ro]:=tot;bg[ro]:=tot;tot:=tot+rosize;ed[ro]:=tot-1; 130 vis[ro]:=true;fa[ro]:=pre; 131 j:=head[ro]; 132 while j>0 do 133 begin 134 if(vis[q[j]]=false)then dfstree(q[j],ro); 135 j:=next[j]; 136 end; 137 end; 138 139 procedure ins(x:longint); 140 var u,f:longint;d:int64; 141 begin 142 u:=x;sum1[now[u]]:=0; 143 while fa[u]<>0 do 144 begin 145 f:=fa[u];d:=dist(x,f); 146 sum1[now[f]]:=d;sum2[now[u]]:=d; 147 u:=f; 148 end; 149 u:=x; 150 while u>0 do 151 begin 152 line[now[u]]:=x;inc(now[u]);u:=fa[u]; 153 end; 154 end; 155 156 function finddown(l,r,x:longint):longint; 157 var mid:longint; 158 begin 159 if x<=a[line[l]] then exit(l-1); 160 while l<r do 161 begin 162 mid:=(l+r)div 2; 163 if a[line[mid+1]]>=x then r:=mid else l:=mid+1; 164 end; 165 exit(l); 166 end; 167 168 function findup(l,r,x:longint):longint; 169 var mid:longint; 170 begin 171 if x<a[line[l]] then exit(l-1); 172 if x>=a[line[r]] then exit(r); 173 while l<r do 174 begin 175 mid:=(l+r)div 2; 176 if a[line[mid+1]]>x then r:=mid else l:=mid+1; 177 end; 178 exit(l); 179 end; 180 181 procedure solve(x:longint); 182 var u,f,l,r,pl,pr:longint;d:int64; 183 begin 184 l:=finddown(bg[x],ed[x],ll);r:=findup(bg[x],ed[x],rr); 185 inc(ans,sum1[r]-sum1[l]);u:=x;pl:=l;pr:=r; 186 while fa[u]<>0 do 187 begin 188 f:=fa[u];d:=dist(x,f); 189 l:=finddown(bg[f],ed[f],ll);r:=findup(bg[f],ed[f],rr); 190 ans:=ans+sum1[r]-sum1[l]+d*(r-l); 191 ans:=ans-(sum2[pr]-sum2[pl])-d*(pr-pl); 192 u:=f;pl:=l;pr:=r; 193 end; 194 end; 195 196 begin 197 readln(n,m,aa); 198 for i:=1 to n do begin read(a[i]);ps[i]:=i; end; 199 sort(1,n); 200 for i:=1 to n-1 do 201 begin 202 readln(u,v,w);addd(u,v,w);addd(v,u,w); 203 end; 204 dfsst(1,0);getst; 205 tot:=1;dfstree(1,0); 206 for i:=1 to n do ins(ps[i]); 207 for i:=1 to tot do 208 begin 209 inc(sum1[i],sum1[i-1]);inc(sum2[i],sum2[i-1]); 210 end; 211 for i:=1 to m do 212 begin 213 readln(u,ax,bx); 214 ll:=min((ax+ans)mod aa,(bx+ans)mod aa); 215 rr:=max((ax+ans)mod aa,(bx+ans)mod aa); 216 ans:=0;solve(u);writeln(ans); 217 end; 218 end.