zoukankan      html  css  js  c++  java
  • bzoj1984

    树链剖分在边上的应用
    比维护点稍微麻烦一点,是对每条边标号,并且要记录每个点父亲边的编号和重儿子
    然后注意各种细节
    线段树上和bzoj1858的维护方法类似,覆盖的优先级高于加
    具体见程序,完全是为了提升状态的练习

      1 type node=record
      2        po,next,num:longint;
      3      end;
      4 
      5 var son,a,d,fa,fp,f2,b,c,p,size,top:array[0..100010] of longint;
      6     w:array[0..200010] of node;
      7     tree,laz1,laz2:array[0..100010*4] of longint;
      8     x,y,z,i,n,t:longint;
      9     ch:char;
     10     s:string;
     11 
     12 function max(a,b:longint):longint;
     13   begin
     14     if a>b then exit(a) else exit(b);
     15   end;
     16 
     17 procedure add(x,y,c:longint);
     18   begin
     19     inc(t);
     20     w[t].po:=y;
     21     w[t].num:=c;
     22     w[t].next:=p[x];
     23     p[x]:=t;
     24   end;
     25 
     26 procedure swap(var a,b:longint);
     27   var c:longint;
     28   begin
     29     c:=a;
     30     a:=b;
     31     b:=c;
     32   end;
     33 
     34 procedure push(i:longint);
     35   begin
     36     if laz1[i]<>-1 then
     37     begin
     38       tree[i*2]:=laz1[i];
     39       tree[i*2+1]:=laz1[i];
     40       laz1[i*2]:=laz1[i];
     41       laz1[i*2+1]:=laz1[i];
     42       laz1[i]:=-1;
     43       laz2[i]:=0;
     44     end;
     45     if laz2[i]<>0 then
     46     begin
     47       inc(tree[i*2],laz2[i]);
     48       inc(tree[i*2+1],laz2[i]);
     49       if laz1[i*2]<>-1 then inc(laz1[i*2],laz2[i])
     50       else inc(laz2[i*2],laz2[i]);
     51       if laz1[i*2+1]<>-1 then inc(laz1[i*2+1],laz2[i])
     52       else inc(laz2[i*2+1],laz2[i]);
     53       laz2[i]:=0;
     54     end;
     55   end;
     56 
     57 procedure dfs1(x:longint);
     58   var i,y:longint;
     59   begin
     60     i:=p[x];
     61     size[x]:=1;
     62     while i<>0 do
     63     begin
     64       y:=w[i].po;
     65       if fa[x]<>y then
     66       begin
     67         fp[y]:=w[i].num;
     68         fa[y]:=x;
     69         d[y]:=d[x]+1;
     70         dfs1(y);
     71         size[x]:=size[x]+size[y];
     72       end;
     73       i:=w[i].next;
     74     end;
     75   end;
     76 
     77 procedure dfs2(x:longint);
     78   var i,y,q:longint;
     79   begin
     80     i:=p[x];
     81     q:=0;
     82     while i<>0 do
     83     begin
     84       if fa[w[i].po]=x then
     85         if size[w[q].po]<size[w[i].po] then q:=i;
     86       i:=w[i].next;
     87     end;
     88     if q=0 then exit;
     89     top[w[q].po]:=top[x];
     90     son[x]:=w[q].num;
     91     inc(t);
     92     c[t]:=w[q].num;
     93     b[w[q].num]:=t;
     94     dfs2(w[q].po);
     95     i:=p[x];
     96     while i<>0 do
     97     begin
     98       y:=w[i].po;
     99       if (i<>q) and (fa[y]=x) then
    100       begin
    101         inc(t);
    102         c[t]:=w[i].num;
    103         b[w[i].num]:=t;
    104         top[y]:=y;
    105         dfs2(y);
    106       end;
    107       i:=w[i].next;
    108     end;
    109   end;
    110 
    111 procedure build(i,l,r:longint);
    112   var m:longint;
    113   begin
    114     laz1[i]:=-1;
    115     laz2[i]:=0;
    116     if l=r then tree[i]:=a[c[l]]
    117     else begin
    118       m:=(l+r) shr 1;
    119       build(i*2,l,m);
    120       build(i*2+1,m+1,r);
    121       tree[i]:=max(tree[i*2],tree[i*2+1]);
    122     end;
    123   end;
    124 
    125 procedure change(i,l,r,x,y,z:longint);
    126   var m:longint;
    127   begin
    128     if x>y then exit;
    129     if (x<=l) and (y>=r) then
    130     begin
    131       laz1[i]:=z;
    132       tree[i]:=z;
    133       laz2[i]:=0;
    134     end
    135     else begin
    136       push(i);
    137       m:=(l+r) shr 1;
    138       if x<=m then change(i*2,l,m,x,y,z);
    139       if y>m then change(i*2+1,m+1,r,x,y,z);
    140       tree[i]:=max(tree[i*2],tree[i*2+1]);
    141     end;
    142   end;
    143 
    144 procedure fadd(i,l,r,x,y:longint);
    145   var m:longint;
    146   begin
    147     if x>y then exit;
    148     if (x<=l) and (y>=r) then
    149     begin
    150       if laz1[i]<>-1 then inc(laz1[i],z)
    151       else inc(laz2[i],z);
    152       inc(tree[i],z);
    153     end
    154     else begin
    155       push(i);
    156       m:=(l+r) shr 1;
    157       if x<=m then fadd(i*2,l,m,x,y);
    158       if y>m then fadd(i*2+1,m+1,r,x,y);
    159       tree[i]:=max(tree[i*2],tree[i*2+1]);
    160     end;
    161   end;
    162 
    163 function getans(i,l,r,x,y:longint):longint;
    164   var m,s:longint;
    165   begin
    166     if x>y then exit(0);
    167     if (x<=l) and (y>=r) then exit(tree[i])
    168     else begin
    169       push(i);
    170       m:=(l+r) shr 1;
    171       s:=0;
    172       if x<=m then s:=getans(i*2,l,m,x,y);
    173       if y>m then s:=max(s,getans(i*2+1,m+1,r,x,y));
    174       exit(s);
    175     end;
    176   end;
    177 
    178 procedure cover(x,y:longint);
    179   var f1,f2:longint;
    180   begin
    181     f1:=top[x];
    182     f2:=top[y];
    183     while f1<>f2 do
    184     begin
    185       if d[f1]>=d[f2] then
    186       begin
    187         change(1,1,n-1,b[fp[f1]],b[fp[x]],z);
    188         x:=fa[f1];
    189       end
    190       else begin
    191         change(1,1,n-1,b[fp[f2]],b[fp[y]],z);
    192         y:=fa[f2];
    193       end;
    194       f1:=top[x];
    195       f2:=top[y];
    196     end;
    197     if x=y then exit
    198     else if b[fp[x]]>b[fp[y]] then swap(x,y);
    199     change(1,1,n-1,b[son[x]],b[fp[y]],z);
    200   end;
    201 
    202 procedure add(x,y:longint);
    203   var f1,f2:longint;
    204   begin
    205     f1:=top[x];
    206     f2:=top[y];
    207     while f1<>f2 do
    208     begin
    209       if d[f1]>=d[f2] then
    210       begin
    211         fadd(1,1,n-1,b[fp[f1]],b[fp[x]]);
    212         x:=fa[f1];
    213       end
    214       else begin
    215         fadd(1,1,n-1,b[fp[f2]],b[fp[y]]);
    216         y:=fa[f2];
    217       end;
    218       f1:=top[x];
    219       f2:=top[y];
    220     end;
    221     if x=y then exit
    222     else if b[fp[x]]>b[fp[y]] then swap(x,y);
    223     fadd(1,1,n-1,b[son[x]],b[fp[y]]);
    224   end;
    225 
    226 function ask(x,y:longint):longint;
    227   var s,f1,f2:longint;
    228   begin
    229     s:=0;
    230     f1:=top[x];
    231     f2:=top[y];
    232     while f1<>f2 do
    233     begin
    234       if d[f1]>=d[f2] then
    235       begin
    236         s:=max(s,getans(1,1,n-1,b[fp[f1]],b[fp[x]]));
    237         x:=fa[f1];
    238       end
    239       else begin
    240         s:=max(s,getans(1,1,n-1,b[fp[f2]],b[fp[y]]));
    241         y:=fa[f2];
    242       end;
    243       f1:=top[x];
    244       f2:=top[y];
    245     end;
    246     if x=y then exit(s)
    247     else if b[fp[x]]>b[fp[y]] then swap(x,y);
    248     s:=max(s,getans(1,1,n-1,b[son[x]],b[fp[y]]));
    249     exit(s);
    250   end;
    251 
    252 begin
    253   readln(n);
    254   for i:=1 to n-1 do
    255   begin
    256     readln(x,y,a[i]);
    257     add(x,y,i);
    258     add(y,x,i);
    259   end;
    260   t:=0;
    261   dfs1(1);
    262   top[1]:=1;
    263   dfs2(1);
    264   while true do
    265   begin
    266     read(ch);
    267     s:='';
    268     while ch<>' ' do
    269     begin
    270       s:=s+ch;
    271       if s='Stop' then halt;
    272       read(ch);
    273     end;
    274     read(x,y);
    275     if s='Max' then
    276       writeln(ask(x,y))
    277     else if s='Change' then
    278       change(1,1,n-1,b[x],b[x],y)
    279     else if s='Cover' then
    280     begin
    281       read(z);
    282       cover(x,y);
    283     end
    284     else if s='Add' then
    285     begin
    286       read(z);
    287       add(x,y);
    288     end;
    289     readln;
    290   end;
    291 end.
    View Code
  • 相关阅读:
    Java怎样对一个属性设置set或get方法的快捷键
    小程序怎样控制rich-text中的<img>标签自适应
    Java中Arrys数组常用的方法
    Java 怎样实现调用其他方法
    Java保留两位小数
    解决ajax请求跨域
    rand(7) 到rand(10)
    c++生成随机数
    批量该文件名
    正则表达式(=)
  • 原文地址:https://www.cnblogs.com/phile/p/4473012.html
Copyright © 2011-2022 走看看