• bzoj3672


    感觉是noi2014中最有价值的一道题了

    我们先考虑链上这个问题怎么做……

    如果没限制,那就是SB的斜率优化

    我们可以得到这个式子(f[j]-f[k])/(s[j]-s[k])<p[i]

    点横坐标是单调的,我们只要维护凸壳然后二分即可

    有距离限制?好像不好弄,不过我们记得cash那道坐标不单调的题我们是可以用cdq分治的

    这道题也一样,划分,考虑左半部分对右半部分的影响

    我们只要对右半部分距离限制排序然后依次加点维护凸壳然后二分即可

    换到树上来那就是点分治啦,

    我们找重心,先做重心子树外(就是包含根的那部分),做完之后

    考虑重心的祖先对子树的影响,我们完全可以如法炮制

    然后不断向下递归处理即可

    这样noi2014的传统题就做完啦!

      1 const inf=9223372036854775807;
      2       eps=1e-10;
      3 
      4 type node=record
      5        po,next:longint;
      6      end;
      7      point=record
      8        x,y:int64;
      9      end;
     10 
     11 var h,fp,p,fa,mx,s,q,b:array[0..200010] of longint;
     12     a:array[0..200010] of point;
     13     cut:array[0..200010] of boolean;
     14     e:array[0..200010] of node;
     15     w,f,d,kp,bp,lim:array[0..200010] of int64;
     16     x,t,i,len,n,ty,r:longint;
     17 
     18 function max(a,b:longint):longint;
     19   begin
     20     if a>b then exit(a) else exit(b);
     21   end;
     22 
     23 procedure min(var a:int64; b:int64);
     24   begin
     25     if a>b then a:=b;
     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 bfs(st:longint);
     37   var i,f,x,y:longint;
     38   begin
     39     f:=1;
     40     r:=1;
     41     q[1]:=st;
     42     while f<=r do
     43     begin
     44       x:=q[f];
     45       i:=p[x];
     46       while i<>0 do
     47       begin
     48         if not cut[i] then
     49         begin
     50           inc(r);
     51           q[r]:=e[i].po;
     52         end;
     53         i:=e[i].next;
     54       end;
     55       inc(f);
     56     end;
     57   end;
     58 
     59 procedure swap(var a,b:longint);
     60   var c:longint;
     61   begin
     62     c:=a;
     63     a:=b;
     64     b:=c;
     65   end;
     66 
     67 function cmp(i,j:longint):boolean;
     68   begin
     69     exit(lim[i]-d[i]<lim[j]-d[j]);
     70   end;
     71 
     72 procedure sort(l,r:longint);
     73   var i,j,x:longint;
     74   begin
     75     i:=l;
     76     j:=r;
     77     x:=b[(l+r) shr 1];
     78     repeat
     79       while cmp(b[i],x) do inc(i);
     80       while cmp(x,b[j]) do dec(j);
     81       if i<=j then
     82       begin
     83         swap(b[i],b[j]);
     84         inc(i);
     85         dec(j);
     86       end;
     87     until i>j;
     88     if l<j then sort(l,j);
     89     if i<r then sort(i,r);
     90   end;
     91 
     92 function getk(i,j:longint):extended;
     93   begin
     94     exit((a[i].y-a[j].y)/(a[i].x-a[j].x));
     95   end;
     96 
     97 function find(l,r,x:longint):longint;
     98   var m:longint;
     99       s1,s2:int64;
    100   begin
    101     while l<r do
    102     begin
    103       m:=(l+r) shr 1;
    104       s1:=a[h[m]].y+a[h[m]].x*kp[x];
    105       s2:=a[h[m+1]].y+a[h[m+1]].x*kp[x];
    106       if s1>s2 then l:=m+1
    107       else r:=m;
    108     end;
    109     exit(h[l]);
    110   end;
    111 
    112 procedure cdq(root:longint);
    113   var i,j,x,mid,m,y:longint;
    114   begin
    115     bfs(root);
    116     if r=1 then exit;
    117     mid:=0;
    118     for i:=r downto 1 do
    119     begin
    120       x:=q[i];
    121       s[x]:=1;
    122       mx[x]:=0;
    123       j:=p[x];
    124       while j<>0 do
    125       begin
    126         y:=e[j].po;
    127         if not cut[j] then
    128         begin
    129           s[x]:=s[x]+s[y];
    130           mx[x]:=max(mx[x],s[y]);
    131         end;
    132         j:=e[j].next;
    133       end;
    134       mx[x]:=max(mx[x],r-s[x]);
    135       if mx[x]<mx[mid] then mid:=x;
    136     end;
    137     if root<>mid then
    138     begin
    139       cut[fp[mid]]:=true;
    140       cdq(root);
    141       m:=0;
    142       x:=fa[mid];
    143       while x<>root do
    144       begin
    145         inc(m);
    146         a[m].x:=-d[x];  //为了方便改变一下形式
    147         a[m].y:=f[x];
    148         x:=fa[x];
    149       end;
    150       inc(m);
    151       a[m].x:=-d[x];
    152       a[m].y:=f[x];
    153 
    154       bfs(mid);
    155       for i:=1 to r do
    156         b[i]:=q[i];
    157       sort(1,r);
    158       t:=0;
    159       j:=1;
    160       for i:=1 to r do
    161       begin
    162         x:=b[i];
    163         while (j<=m) and (a[j].x<=lim[x]-d[x]) do
    164         begin
    165           while (t>1) and (getk(j,h[t])-eps<getk(h[t],h[t-1])) do dec(t);
    166           inc(t);
    167           h[t]:=j;
    168           inc(j);
    169         end;
    170         if t>0 then
    171         begin
    172           y:=find(1,t,x);
    173           min(f[x],a[y].y+kp[x]*(d[x]+a[y].x)+bp[x]);
    174         end;
    175       end;
    176     end;
    177     for i:=2 to r do
    178     begin
    179       x:=q[i];
    180       if d[x]-d[mid]<=lim[x] then
    181         min(f[x],f[mid]+kp[x]*(d[x]-d[mid])+bp[x]);
    182     end;
    183     i:=p[mid];
    184     while i<>0 do
    185     begin
    186       if not cut[i] then cdq(e[i].po);
    187       i:=e[i].next;
    188     end;
    189   end;
    190 
    191 begin
    192   readln(n,ty);
    193   for i:=2 to n do
    194   begin
    195     readln(fa[i],w[i],kp[i],bp[i],lim[i]);
    196     add(fa[i],i);
    197     fp[i]:=len;
    198     f[i]:=inf;
    199   end;
    200   bfs(1);
    201   for i:=2 to r do
    202   begin
    203     x:=q[i];
    204     d[x]:=d[fa[x]]+w[x];
    205   end;
    206   mx[0]:=n+1;
    207   f[1]:=0;
    208   cdq(1);
    209   for i:=2 to n do
    210     writeln(f[i]);
    211 end.
    View Code
  • 相关阅读:
    Jenkins持续集成
    爬豆瓣保存到sqlite3
    爬豆瓣保存到Excel
    sqlite3数据库的增删查改
    用pandas和matplotlib对用户消费行为分析
    TCP请求
    fastjson
    断言
    将结果写入文件
    加解密
  • 原文地址:https://www.cnblogs.com/phile/p/4590686.html
Copyright © 2020-2023  润新知