• bzoj1036


    树链剖分的基本题
    详细介绍在http://blog.sina.com.cn/s/blog_7a1746820100wp67.html
    通过树链剖分我们就可以在树上做线段树操作,完成解答

      1 const inf=2147483647;
      2 type node=record
      3        po,next:longint;
      4      end;
      5      point=record
      6        max,sum:longint;
      7      end;
      8 
      9 
     10 var tree:array[0..120010] of point;
     11     size,d,fa,p,b,c,top:array[0..30010] of longint;
     12     w:array[0..80010] of node;
     13     len,i,n,m,x,y,t:longint;
     14     ch:char;
     15     s:string;
     16 
     17 function max(a,b:longint):longint;
     18   begin
     19     if a>b then exit(a) else exit(b);
     20   end;
     21 
     22 procedure update(i:longint);
     23   begin
     24     tree[i].sum:=tree[i*2].sum+tree[i*2+1].sum;
     25     tree[i].max:=max(tree[i*2].max,tree[i*2+1].max);
     26   end;
     27 
     28 procedure swap(var a,b:longint);
     29   var c:longint;
     30   begin
     31     c:=a;
     32     a:=b;
     33     b:=c;
     34   end;
     35 
     36 procedure add(x,y:longint);
     37   begin
     38     inc(len);
     39     w[len].po:=y;
     40     w[len].next:=p[x];
     41     p[x]:=len;
     42   end;
     43 
     44 procedure dfs1(x:longint);  //预处理
     45   var i,y:longint;
     46   begin
     47     i:=p[x];
     48     size[x]:=1;
     49     while i<>0 do
     50     begin
     51       y:=w[i].po;
     52       if fa[x]<>y then
     53       begin
     54         fa[y]:=x;
     55         d[y]:=d[x]+1;
     56         dfs1(y);
     57         size[x]:=size[x]+size[y];
     58       end;
     59       i:=w[i].next;
     60     end;
     61   end;
     62 
     63 procedure dfs2(x:longint);
     64   var i,y,q:longint;
     65   begin
     66     i:=p[x];
     67     inc(t);
     68     c[x]:=t;
     69     q:=0;
     70     while i<>0 do
     71     begin
     72       y:=w[i].po;
     73       if (c[y]=0) and (size[q]<size[y]) then q:=y;
     74       i:=w[i].next;
     75     end;
     76     if q<>0 then
     77     begin
     78       top[q]:=top[x];  //重儿子先访问
     79       dfs2(q);
     80     end;
     81     i:=p[x];  //然后访问轻儿子
     82     while i<>0 do
     83     begin
     84       y:=w[i].po;
     85       if c[y]=0 then
     86       begin
     87         top[y]:=y;
     88         dfs2(y);
     89       end;
     90       i:=w[i].next;
     91     end;
     92   end;
     93 
     94 procedure build(i,l,r:longint);
     95   var m:longint;
     96   begin
     97     if l=r then
     98     begin
     99       tree[i].sum:=b[l];
    100       tree[i].max:=b[l];
    101     end
    102     else begin
    103       m:=(l+r) shr 1;
    104       build(i*2,l,m);
    105       build(i*2+1,m+1,r);
    106       update(i);
    107     end;
    108   end;
    109 
    110 procedure add(i,l,r:longint);
    111   var m:longint;
    112   begin
    113     if l=r then
    114     begin
    115       tree[i].sum:=y;
    116       tree[i].max:=y;
    117     end
    118     else begin
    119       m:=(l+r) shr 1;
    120       if x<=m then add(i*2,l,m) else add(i*2+1,m+1,r);
    121       update(i);
    122     end;
    123   end;
    124 
    125 function getmax(i,l,r,x,y:longint):longint;
    126   var m,t:longint;
    127   begin
    128     if (x<=l) and (y>=r) then exit(tree[i].max)
    129     else begin
    130       m:=(l+r) shr 1;
    131       t:=-inf;
    132       if x<=m then t:=max(t,getmax(i*2,l,m,x,y));
    133       if y>m then t:=max(t,getmax(i*2+1,m+1,r,x,y));
    134       exit(t);
    135     end;
    136   end;
    137 
    138 function getsum(i,l,r,x,y:longint):longint;
    139   var m,t:longint;
    140   begin
    141     if (x<=l) and (y>=r) then exit(tree[i].sum)
    142     else begin
    143       m:=(l+r) shr 1;
    144       t:=0;
    145       if x<=m then t:=t+getsum(i*2,l,m,x,y);
    146       if y>m then t:=t+getsum(i*2+1,m+1,r,x,y);
    147       exit(t);
    148     end;
    149   end;
    150 
    151 function asksum(x,y:longint):longint;
    152   var f1,f2:longint;
    153   begin
    154     asksum:=0;
    155     f1:=top[x];
    156     f2:=top[y];
    157     while f1<>f2 do
    158     begin
    159       if d[f1]>=d[f2] then
    160       begin
    161         asksum:=asksum+getsum(1,1,n,c[f1],c[x]);
    162         x:=fa[f1];
    163       end
    164       else begin
    165         asksum:=asksum+getsum(1,1,n,c[f2],c[y]);
    166         y:=fa[f2];
    167       end;
    168       f1:=top[x];
    169       f2:=top[y];
    170     end;
    171     if c[x]>c[y] then swap(x,y);
    172     asksum:=asksum+getsum(1,1,n,c[x],c[y]);
    173   end;
    174 
    175 function askmax(x,y:longint):longint;
    176   var f1,f2,t:longint;
    177   begin
    178     t:=-inf;
    179     f1:=top[x];
    180     f2:=top[y];
    181     while f1<>f2 do  //提取
    182     begin
    183       if d[f1]>=d[f2] then
    184       begin
    185         t:=max(t,getmax(1,1,n,c[f1],c[x]));
    186         x:=fa[f1];
    187       end
    188       else begin
    189         t:=max(t,getmax(1,1,n,c[f2],c[y]));
    190         y:=fa[f2];
    191       end;
    192       f1:=top[x];
    193       f2:=top[y];
    194     end;
    195     if c[x]>c[y] then swap(x,y);
    196     t:=max(t,getmax(1,1,n,c[x],c[y]));
    197     exit(t);
    198   end;
    199 
    200 begin
    201   readln(n);
    202   for i:=1 to n-1 do
    203   begin
    204     readln(x,y);
    205     add(x,y);
    206     add(y,x);
    207   end;
    208   d[1]:=1;
    209   dfs1(1);
    210   t:=0;
    211   top[1]:=1;
    212   dfs2(1);
    213   for i:=1 to n do
    214     read(b[c[i]]);
    215   build(1,1,n);
    216   readln(m);
    217   for i:=1 to m do
    218   begin
    219     read(ch);
    220     s:='';
    221     while ch<>' ' do
    222     begin
    223       s:=s+ch;
    224       read(ch);
    225     end;
    226     readln(x,y);
    227     if s='QMAX' then
    228       writeln(askmax(x,y))
    229     else if s='QSUM' then
    230       writeln(asksum(x,y))
    231     else if s='CHANGE' then
    232     begin
    233       x:=c[x];
    234       b[x]:=y;
    235       add(1,1,n);
    236     end;
    237   end;
    238 end.
    View Code
  • 相关阅读:
    自己写的SqlHelper
    宿叶网思路
    phpMyAdmin教程 之 创建新用户/导入/导出数据库
    什么是主机空间?干什么用?
    转 sql注入
    xUtils
    仿360状态,类流量监控桌面浮动显示
    在Yii Framework中利用PHPMailer发送邮件(2011-06-02 14:06:23)
    MD5类库(hex_md5)
    MYSQL的随机查询的实现方法
  • 原文地址:https://www.cnblogs.com/phile/p/4473093.html
Copyright © 2020-2023  润新知