zoukankan      html  css  js  c++  java
  • 1036: [ZJOI2008]树的统计Count

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 7496  Solved: 3078
    [Submit][Status][Discuss]

    Description

    一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。我们将以下面的形式来要求你对这棵树完成一些操作: I. CHANGE u t : 把结点u的权值改为t II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值 III. QSUM u v: 询问从点u到点v的路径上的节点的权值和 注意:从点u到点v的路径上的节点包括u和v本身

    Input

    输入的第一行为一个整数n,表示节点的个数。接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。接下来1行,为一个整数q,表示操作的总数。接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。 对于100%的数据,保证1<=n<=30000,0<=q<=200000;中途操作中保证每个节点的权值w在-30000到30000之间。

    Output

    对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。

    Sample Input

    4
    1 2
    2 3
    4 1
    4 2 1 3
    12
    QMAX 3 4
    QMAX 3 3
    QMAX 3 2
    QMAX 2 3
    QSUM 3 4
    QSUM 2 1
    CHANGE 1 5
    QMAX 3 4
    CHANGE 3 6
    QMAX 3 4
    QMAX 2 4
    QSUM 3 4

    Sample Output

    4
    1
    2
    2
    10
    6
    5
    6
    5
    16

    HINT

     

    Source

    树的分治

    题解:phile神犇推荐的链剖模板题,一直不知道为啥挂掉,急死掉= =,最后发现居然把inline去掉就A了QAQ,逗我= =

    事实证明——(引用phile神犇的原话)黑科技不可滥用TT

      1 type
      2     point=^node;
      3     node=record
      4                g:longint;
      5                next:point;
      6     end;
      7 var
      8    i,j,k,l,m,n,tot,root:longint;a1:int64;
      9    a:array[0..100000] of point;ch:char;
     10    d,e:array[0..500000] of int64;
     11    len,son,siz,top,list,f,num,anum:array[0..100000] of longint;
     12    c:array[0..20,0..100000] of longint;
     13 function min(x,y:longint):longint;
     14          begin
     15               if x<y then min:=x else min:=y;
     16          end;
     17 function max(x,y:longint):longint;
     18          begin
     19               if x>y then max:=x else max:=y;
     20          end;
     21 procedure swap(var x,y:longint);
     22           var z:longint;
     23           begin
     24                z:=x;x:=y;y:=z;
     25           end;
     26 procedure add(x,y:longint);
     27           var p:point;
     28           begin
     29                new(p);p^.g:=y;p^.next:=a[x];a[x]:=p;
     30           end;
     31 procedure dfs(y,x:longint);
     32           var p:point;
     33           begin
     34                c[0,x]:=y;siz[x]:=1;len[x]:=len[y]+1;son[x]:=0;
     35                p:=a[x];
     36                while p<>nil do
     37                      begin
     38                           if p^.g<>y then
     39                              begin
     40                                   dfs(x,p^.g);
     41                                   inc(siz[x],siz[p^.g]);
     42                                   if (son[x]=0) or (siz[p^.g]>siz[son[x]]) then son[x]:=p^.g;
     43                              end;
     44                           p:=p^.next;
     45                      end;
     46           end;
     47 procedure dfs2(y,x,z:longint);
     48           var p:point;
     49           begin
     50                top[x]:=z;inc(tot);num[x]:=tot;anum[tot]:=x;
     51                if son[x]<>0 then dfs2(x,son[x],z);p:=a[x];
     52                while p<>nil do
     53                      begin
     54                           if (p^.g<>y) and (p^.g<>son[x]) then dfs2(x,p^.g,p^.g);
     55                           p:=p^.next;
     56                      end;
     57           end;
     58 procedure built(z,x,y:longint);
     59           begin
     60                if x=y then
     61                   begin
     62                        list[x]:=z;
     63                        d[z]:=f[anum[x]];
     64                        e[z]:=d[z];
     65                   end
     66                else
     67                    begin
     68                         built(z*2,x ,(x+y) div 2);
     69                         built(z*2+1,(x+y) div 2+1,y);
     70                         d[z]:=d[z*2]+d[z*2+1];
     71                         if e[z*2+1]>e[z*2] then e[z]:=e[z*2+1] else e[z]:=e[z*2];
     72                    end;
     73           end;
     74 procedure change(x:longint;y:int64);
     75          begin
     76               x:=list[x];d[x]:=y;e[x]:=y;x:=x div 2;
     77               while x>0 do
     78                     begin
     79                          d[x]:=d[x*2]+d[x*2+1];
     80                          if e[x*2+1]>e[x*2] then e[x]:=e[x*2+1] else e[x]:=e[x*2];
     81                          x:=x div 2;
     82                     end;
     83          end;
     84 function sum(z,x,y,l,r:longint):int64;
     85          begin
     86               if l>r then exit(0);
     87               if (x=l) and (y=r) then exit(d[z]);
     88               exit(sum(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2))+sum(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r));
     89          end;
     90 function getmax(z,x,y,l,r:longint):int64;
     91          var a1,a2:int64;
     92          begin
     93               if l>r then exit(-maxlongint*maxlongint);
     94               if (x=l) and (y=r) then exit(e[z]);
     95               a1:=getmax(z*2,x,(x+y) div 2,l,min(r,(x+y) div 2));
     96               a2:=getmax(z*2+1,(x+y) div 2+1,y,max((x+y) div 2+1,l),r);
     97               if a1>a2 then exit(a1) else exit(a2);
     98          end;
     99 function getup(x,y:longint):longint;
    100          var i:longint;
    101          begin
    102               i:=0;
    103               while y>0 do
    104                     begin
    105                          if odd(y) then x:=c[i,x];
    106                          inc(i);y:=y div 2;
    107                     end;
    108               exit(x);
    109          end;
    110 function getcom(x,y:longint):longint;
    111          var i:longint;
    112          begin
    113               if len[x]<len[y] then swap(x,y);
    114               x:=getup(x,len[x]-len[y]);
    115               if x=y then exit(x);
    116               for i:=trunc(round(ln(len[x])/ln(2))) downto 0 do
    117                   if c[i,x]<>c[i,y] then
    118                      begin
    119                           x:=c[i,x];
    120                           y:=c[i,y];
    121                      end;
    122               exit(c[0,x]);
    123          end;
    124 procedure treechange(x:longint;y:int64);
    125           begin
    126                change(num[x],y);
    127           end;
    128 function treesum(x,y:longint):int64;
    129           var i,z:longint;
    130           begin
    131                z:=getcom(x,y);treesum:=0;
    132                repeat
    133                      if len[top[x]]<len[z] then i:=z else i:=top[x];
    134                      inc(treesum,sum(1,1,n,num[i],num[x]));
    135                      if i=z then break;
    136                      x:=c[0,i];
    137                until false;
    138                repeat
    139                      if len[top[y]]<len[z] then i:=z else i:=top[y];
    140                      inc(treesum,sum(1,1,n,num[i],num[y]));
    141                      if i=z then break;
    142                      y:=c[0,i];
    143                until false;
    144                dec(treesum,sum(1,1,n,num[z],num[z]));
    145           end;
    146 function treemax(x,y:longint):int64;
    147          var i,z:longint;a1:int64;
    148          begin
    149               treemax:=-maxlongint*maxlongint;
    150               z:=getcom(x,y);
    151               repeat
    152                     if len[top[x]]<len[z] then i:=z else i:=top[x];
    153                     a1:=getmax(1,1,n,num[i],num[x]);
    154                     if a1>treemax then treemax:=a1;
    155                     if i=z then break;
    156                     x:=c[0,i];
    157               until false;
    158               repeat
    159                     if len[top[y]]<len[z] then i:=z else i:=top[y];
    160                     a1:=getmax(1,1,n,num[i],num[y]);
    161                     if a1>treemax then treemax:=a1;
    162                     if i=z then break;
    163                     y:=c[0,i];
    164               until false;
    165          end;
    166 begin
    167      readln(n);
    168      for i:=1 to n do a[i]:=nil;
    169      for i:=1 to n-1 do
    170          begin
    171               readln(j,k);
    172               add(j,k);add(k,j);
    173          end;
    174      for i:=1 to n do read(f[i]);readln;
    175      root:=random(n)+1;dfs(0,root);dfs2(0,root,root);
    176      for i:=1 to trunc(round(ln(n)/ln(2)))+1 do
    177          for j:=1 to n do
    178              c[i,j]:=c[i-1,c[i-1,j]];
    179      built(1,1,n);
    180      readln(m);
    181      for i:=1 to m do
    182          begin
    183               read(ch,ch);
    184               case upcase(ch) of
    185                    'M':begin
    186                             readln(ch,ch,j,k);
    187                             writeln(treemax(j,k));
    188                    end;
    189                    'S':begin
    190                             readln(ch,ch,j,k);
    191                             writeln(treesum(j,k));
    192                    end;
    193                    'H':begin
    194                             readln(ch,ch,ch,ch,j,a1);
    195                             treechange(j,a1);
    196                    end;
    197               end;
    198          end;
    199      readln;
    200 end.
  • 相关阅读:
    AngularJs 与Jquery的对比分析,超详细!
    身份证号验证,获取户口地址、性别、出生日期
    前端面试·
    页面可见性(Page Visibility API) 可以有哪些用途?
    webSocket如何兼容低浏览器?(阿里)
    如何实现浏览器内多个标签页之间的通信?
    HTML5的form如何关闭自动完成功能?
    Label的作用是什么?是怎么用的?
    cookies,sessionStorage 和 localStorage 的区别?
    浏览器是怎么对HTML5的离线储存资源进行管理和加载的呢?
  • 原文地址:https://www.cnblogs.com/HansBug/p/4498802.html
Copyright © 2011-2022 走看看