zoukankan      html  css  js  c++  java
  • bzoj1036 [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 program rrr(input,output);
      2 type
      3   tree=record
      4      l,r,sum,max:longint;
      5   end;
      6   pointer=^nodetype;
      7   nodetype=record
      8      t:longint;
      9      next:pointer;
     10   end;
     11 var
     12   a:array[0..4*30030]of tree;
     13   b:array[0..30030]of pointer;
     14   p:pointer;
     15   q,dep,belong,head,idx,father,siz,num:array[0..30030]of longint;
     16   v:array[0..30030]of boolean;
     17   n,m,i,j,x,y,h,t,cnt,tot,ans:longint;
     18   s:string;
     19 function max(a,b:longint):longint;
     20 begin
     21    if a>b then exit(a) else exit(b);
     22 end;
     23 procedure add(x,y:longint);
     24 begin
     25    new(p);p^.t:=y;p^.next:=b[x];b[x]:=p;
     26 end;
     27 procedure bfs;
     28 begin
     29    fillchar(v,sizeof(v),false);
     30    h:=0;t:=1;q[1]:=1;dep[1]:=0;v[1]:=true;
     31    while h<t do
     32       begin
     33          inc(h);p:=b[q[h]];
     34          while p<>nil do
     35             begin
     36                if not v[p^.t] then
     37                   begin
     38                      inc(t);q[t]:=p^.t;v[p^.t]:=true;
     39                      dep[p^.t]:=dep[q[h]]+1;father[p^.t]:=q[h];
     40                   end;
     41                p:=p^.next;
     42             end;
     43       end;
     44    for i:=1 to n do siz[i]:=1;
     45    for i:=n downto 2 do inc(siz[father[q[i]]],siz[q[i]]);
     46 end;
     47 procedure dfs(k:longint);
     48 var
     49   p:pointer;
     50   i,max:longint;
     51 begin
     52    if siz[k]=1 then exit;
     53    p:=b[k];max:=0;
     54    while p<>nil do begin if p^.t<>father[k] then if siz[p^.t]>max then begin max:=siz[p^.t];i:=p^.t; end;p:=p^.next; end;
     55    belong[i]:=belong[k];inc(cnt);idx[i]:=cnt;
     56    dfs(i);
     57    if siz[k]=2 then exit;
     58    p:=b[k];
     59    while p<>nil do
     60       begin
     61          if (p^.t<>father[k]) and (p^.t<>i) then
     62             begin
     63                inc(cnt);idx[p^.t]:=cnt;
     64                inc(tot);head[tot]:=p^.t;belong[p^.t]:=tot;
     65                dfs(p^.t);
     66             end;
     67          p:=p^.next;
     68       end;
     69 end;
     70 procedure build(k,l,r:longint);
     71 var
     72   mid,i:longint;
     73 begin
     74    a[k].l:=l;a[k].r:=r;
     75    if l=r then begin a[k].sum:=num[l];a[k].max:=num[l];exit; end;
     76    mid:=(l+r)>>1;i:=k<<1;
     77    build(i,l,mid);build(i+1,mid+1,r);
     78    a[k].max:=max(a[i].max,a[i+1].max);a[k].sum:=a[i].sum+a[i+1].sum;
     79 end;
     80 procedure work;
     81 begin
     82    j:=pos(' ',s);
     83    val(copy(s,1,j-1),x);
     84    delete(s,1,j);val(s,y);
     85 end;
     86 procedure change(k:longint);
     87 var
     88   mid,i:longint;
     89 begin
     90    if a[k].l=a[k].r then begin a[k].max:=y;a[k].sum:=y;exit; end;
     91    mid:=(a[k].l+a[k].r)>>1;i:=k<<1;
     92    if x<=mid then change(i) else change(i+1);
     93    a[k].sum:=a[i].sum+a[i+1].sum;a[k].max:=max(a[i].max,a[i+1].max);
     94 end;
     95 function askmax(k,x,y:longint):longint;
     96 var
     97   mid,i:longint;
     98 begin
     99    if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].max);
    100    mid:=(a[k].l+a[k].r)>>1;i:=k<<1;
    101    askmax:=-30000;
    102    if x<=mid then askmax:=askmax(i,x,y);
    103    if mid<y then askmax:=max(askmax,askmax(i+1,x,y));
    104 end;
    105 function asksum(k,x,y:longint):longint;
    106 var
    107   mid,i:longint;
    108 begin
    109    if (x<=a[k].l) and (a[k].r<=y) then exit(a[k].sum);
    110    mid:=(a[k].l+a[k].r)>>1;i:=k<<1;
    111    asksum:=0;
    112    if x<=mid then asksum:=asksum(i,x,y);
    113    if mid<y then asksum:=asksum+asksum(i+1,x,y);
    114 end;
    115 function ask1:longint;
    116 begin
    117    ans:=-30000;
    118    while belong[x]<>belong[y] do
    119       if dep[head[belong[x]]]>dep[head[belong[y]]] then begin ans:=max(ans,askmax(1,idx[head[belong[x]]],idx[x]));x:=father[head[belong[x]]]; end
    120       else begin ans:=max(ans,askmax(1,idx[head[belong[y]]],idx[y]));y:=father[head[belong[y]]]; end;
    121    if dep[x]>dep[y] then exit(max(ans,askmax(1,idx[y],idx[x])))
    122    else exit(max(ans,askmax(1,idx[x],idx[y])));
    123 end;
    124 function ask2:longint;
    125 begin
    126    ans:=0;
    127    while belong[x]<>belong[y] do
    128       if dep[head[belong[x]]]>dep[head[belong[y]]] then begin ans:=ans+asksum(1,idx[head[belong[x]]],idx[x]);x:=father[head[belong[x]]]; end
    129       else begin ans:=ans+asksum(1,idx[head[belong[y]]],idx[y]);y:=father[head[belong[y]]]; end;
    130    if dep[x]>dep[y] then exit(ans+asksum(1,idx[y],idx[x]))
    131    else exit(ans+asksum(1,idx[x],idx[y]));
    132 end;
    133 begin
    134    assign(input,'r.in');assign(output,'r.out');reset(input);rewrite(output);
    135    readln(n);
    136    for i:=1 to n do b[i]:=nil;
    137    for i:=1 to n-1 do begin readln(x,y);add(x,y);add(y,x); end;
    138    bfs;
    139    belong[1]:=1;head[1]:=1;tot:=1;cnt:=1;idx[1]:=1;
    140    dfs(1);
    141    for i:=1 to n do read(num[idx[i]]);
    142    build(1,1,n);
    143    readln(m);
    144    for i:=1 to m do
    145       begin
    146          readln(s);
    147          if s[2]='M' then begin delete(s,1,5);work;writeln(ask1); end;
    148          if s[2]='S' then begin delete(s,1,5);work;writeln(ask2); end;
    149          if s[2]='H' then begin delete(s,1,7);work;x:=idx[x];change(1); end;
    150       end;
    151    close(input);close(output);
    152 end.

    2017.3.29+

    这个代码是以前写的,用的还是指针存树+dfs初始化

    刚刚又复习了一下这题,用现在的风格写的,主要区别是数组模拟邻接表存树和非递归初始化。

    传送门:

    http://www.cnblogs.com/Currier/p/6642442.html

  • 相关阅读:
    Docker学习笔记(一)——安装
    Mac安装Nginx
    Spring Boot学习笔记(二)——HelloWorld实现
    Spring Boot学习笔记(一)——Eclipse安装STS插件
    Redis学习笔记(九)——集群
    Redis学习笔记(八)——持久化
    Redis学习笔记(七)——数据结构之有序集合(sorted set)
    Redis学习笔记(六)——数据结构之Set
    Redis学习笔记(五)——数据结构之哈希(Hash)
    Redis学习笔记(四)——数据结构之List
  • 原文地址:https://www.cnblogs.com/Currier/p/6388145.html
Copyright © 2011-2022 走看看