• 1036: [ZJOI2008]树的统计Count


    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

    裸树链剖分,我就不多说了,附入门教程

      1 const
      2     maxn=30010;
      3 type
      4     node=record
      5       son:array[0..1]of longint;
      6       sum,max,left,right,mid:longint;
      7     end;
      8 var
      9     n,m,num,tot,xx,ll,rr,goal:longint;
     10     tree:array[0..maxn*2]of node;
     11     first,fa,dep,son,size,w,top,root:array[0..maxn]of longint;
     12     next,last:array[0..maxn*2]of longint;
     13 
     14 procedure insert(x,y:longint);
     15 begin
     16     inc(num);
     17     last[num]:=y;
     18     next[num]:=first[x];
     19     first[x]:=num;
     20 end;
     21 
     22 procedure dfs1(x,d,f:longint);
     23 var
     24     i:longint;
     25 begin
     26     dep[x]:=d;
     27     fa[x]:=f;
     28     size[x]:=1;
     29     i:=first[x];
     30     while i<>0 do
     31       begin
     32         if last[i]<>f then
     33         begin
     34           dfs1(last[i],d+1,x);
     35           if size[last[i]]>size[son[x]] then son[x]:=last[i];
     36           inc(size[x],size[last[i]]);
     37         end;
     38         i:=next[i];
     39       end;
     40 end;
     41 
     42 procedure build(l,r:longint);
     43 var
     44     now:longint;
     45 begin
     46     inc(tot);
     47     now:=tot; 
     48     with tree[now] do
     49       begin
     50         left:=l;
     51         right:=r;
     52         if l=r then exit;
     53         mid:=(l+r)>>1;
     54         son[0]:=tot+1;
     55         build(l,mid);
     56         son[1]:=tot+1;
     57         build(mid+1,r);
     58       end;
     59 end;
     60 
     61 procedure dfs2(x,t,ww:longint);
     62 var
     63     i:longint;
     64 begin
     65     w[x]:=ww;
     66     top[x]:=t;
     67     if son[x]=0 then
     68       begin
     69         root[x]:=tot+1;
     70         build(1,ww);
     71         exit;
     72       end
     73     else
     74       begin
     75         dfs2(son[x],t,ww+1);
     76         root[x]:=root[son[x]];
     77       end;
     78     i:=first[x];
     79     while i<>0 do
     80       begin
     81         if (last[i]<>fa[x]) and (last[i]<>son[x]) then dfs2(last[i],last[i],1);
     82         i:=next[i];
     83       end;
     84 end;
     85 
     86 procedure change(now:longint);
     87 begin
     88     with tree[now] do
     89       begin
     90         if left=right then
     91         begin
     92           sum:=goal;
     93           max:=goal;
     94           exit;
     95         end;
     96         if xx<=mid then change(son[0])
     97         else change(son[1]);
     98         if tree[son[0]].max>tree[son[1]].max then max:=tree[son[0]].max
     99         else max:=tree[son[1]].max;
    100         sum:=tree[son[0]].sum+tree[son[1]].sum;
    101       end;
    102 end;
    103 
    104 function getsum(now:longint):longint;
    105 begin
    106     with tree[now] do
    107       begin
    108         if (ll<=left) and (rr>=right) then exit(sum);
    109         if rr<=mid then exit(getsum(son[0]));
    110         if ll>mid then exit(getsum(son[1]));
    111         exit(getsum(son[0])+getsum(son[1]));
    112       end;
    113 end;
    114 
    115 function getmax(now:longint):longint;
    116 var
    117     s:longint;
    118 begin
    119     with tree[now] do
    120       begin
    121         if (ll<=left) and (rr>=right) then exit(max);
    122         if rr<=mid then exit(getmax(son[0]));
    123         if ll>mid then exit(getmax(son[1]));
    124         getmax:=getmax(son[0]);
    125         s:=getmax(son[1]);
    126         if s>getmax then getmax:=s;
    127       end;
    128 end;
    129 
    130 procedure init;
    131 var
    132     i,x,y:longint;
    133 begin
    134     read(n);
    135     for i:=1 to n-1 do
    136       begin
    137         read(x,y);
    138         insert(x,y);
    139         insert(y,x);
    140       end;
    141     dfs1(1,1,0);
    142     dfs2(1,1,1);
    143     for i:=1 to n do
    144       begin
    145         read(goal);
    146         xx:=w[i];
    147         change(root[i]);
    148       end;
    149 end;
    150 
    151 procedure work;
    152 var
    153     i,ans,s,x,y:longint;
    154     s1,s2:char;
    155 begin
    156     read(m);
    157     for i:=1 to m do
    158       begin
    159         read(s2);
    160         while s2<>' ' do
    161           begin
    162             s1:=s2;
    163             read(s2);
    164           end;
    165         read(x,y);
    166         case s1 of
    167           'E':begin
    168             goal:=y;
    169             xx:=w[x];
    170             change(root[x]);
    171           end;
    172           'X':begin
    173             ans:=-300000;
    174             while top[x]<>top[y] do
    175               begin
    176                 if dep[top[x]]<dep[top[y]] then
    177                 begin
    178                   s:=x;x:=y;y:=s;
    179                 end;
    180                 ll:=1;
    181                 rr:=w[x];
    182                 s:=getmax(root[x]);
    183                 if s>ans then ans:=s;
    184                 x:=fa[top[x]];
    185               end;
    186             if dep[x]<dep[y] then
    187             begin
    188               s:=x;x:=y;y:=s;
    189             end;
    190             ll:=w[y];
    191             rr:=w[x];
    192             s:=getmax(root[x]);
    193             if s>ans then ans:=s;
    194             writeln(ans);
    195           end;
    196           'M':begin
    197             ans:=0;
    198             while top[x]<>top[y] do
    199               begin
    200                 if dep[top[x]]<dep[top[y]] then
    201                 begin
    202                   s:=x;x:=y;y:=s;
    203                 end;
    204                 ll:=1;
    205                 rr:=w[x];
    206                 inc(ans,getsum(root[x]));
    207                 x:=fa[top[x]];
    208               end;
    209             if dep[x]<dep[y] then
    210             begin
    211               s:=x;x:=y;y:=s;
    212             end;
    213             ll:=w[y];
    214             rr:=w[x];
    215             inc(ans,getsum(root[x]));
    216             writeln(ans);
    217           end;
    218         end;
    219       end;
    220 end;
    221 
    222 begin
    223     init;
    224     work;
    225 end.
    View Code
  • 相关阅读:
    UML简介
    Servlet过滤器基础及使用场景
    eclipse maven配置问题:org.apache.maven.archiver.mavenarchiver.getmanifest
    maven中的groupId和artifactId 区分
    Spring中的控制反转和依赖注入
    SQL语句、PL/SQL块和SQL*Plus命令之间的区别
    Mybatis核心类生命周期和管理
    MyBatis Generator 下划线转驼峰命名
    修改maven默认仓库(即repository)的路径
    MyBatis SqlSessionFactory的几种常见创建方式
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3648820.html
Copyright © 2020-2023  润新知