• 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

    Sample Output

    1603
    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.
    View Code
  • 相关阅读:
    Linux文件系统之目录清单
    Linux系统使用iftop查看带宽占用情况
    性能分析之TCP全连接队列占满问题分析及优化过程(转载)
    什么是枚举及枚举的使用场合
    height:100%和height:auto的区别
    Jquery基础之DOM操作
    SSM三大框架整合(Spring+SpringMVC+MyBatis)
    js解析JSON
    mybatis中oracle实现分页效果
    MyBatis动态SQL语句
  • 原文地址:https://www.cnblogs.com/oldjang/p/6920922.html
Copyright © 2020-2023  润新知