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

    1036: [ZJOI2008]树的统计Count

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 4980  Solved: 2095
    [Submit][Status]

    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

     

    题解:

    原来抄着别人的代码稀里糊涂的过了一遍,什么也没懂。。。

    好几次尝试理解树链剖分都失败了。。。

    今天又看发现好水,也许是学了splay之后对数据结构又有兴趣了吧。。。

    查询的时候借鉴了proverbs的方法,不求LCA,直接往上提,代码量也比较少 

    http://www.cnblogs.com/proverbs/archive/2013/01/18/2867092.html

    代码:

      1 {$M 10000000,0,maxlongint}
      2 const maxn=30000+100;
      3 type node1=record
      4      go,next:longint;
      5      end;
      6      node2=record
      7      l,r,mid,mx,sum:longint;
      8      end;
      9 
     10 var  e:array[0..2*maxn] of node1;
     11      t:array[0..4*maxn] of node2;
     12      p,a,v,fa,s,head,dep,son,top:array[0..maxn] of longint;
     13      i,n,m,x,y,xx,yy,sz,ans,tot:longint;
     14      ch:char;
     15      procedure swap(var x,y:longint);
     16       var t:longint;
     17       begin
     18         t:=x;x:=y;y:=t;
     19       end;
     20      procedure insert(x,y:longint);
     21       begin
     22         inc(tot);
     23         e[tot].go:=y;e[tot].next:=head[x];head[x]:=tot;
     24       end;
     25      function min(x,y:longint):longint;
     26       begin
     27         if x<y then exit(x) else exit(y);
     28       end;
     29      function max(x,y:longint):longint;
     30       begin
     31         if x>y then exit(x) else exit(y);
     32       end;
     33 
     34 procedure dfs1(x:longint);
     35  var i,j,y:longint;
     36  begin
     37    j:=0;s[x]:=1;
     38    i:=head[x];
     39    while i<>0 do
     40     begin
     41      y:=e[i].go;
     42      if dep[y]=0 then
     43       begin
     44         dep[y]:=dep[x]+1;
     45         fa[y]:=x;
     46         dfs1(y);
     47         inc(s[x],s[y]);
     48         if s[y]>s[j] then j:=y;
     49       end;
     50      i:=e[i].next;
     51     end;
     52    son[x]:=j;
     53  end;
     54 procedure dfs2(x,chain:longint);
     55  var i,y:longint;
     56  begin
     57    inc(sz);p[x]:=sz;top[x]:=chain;
     58    if son[x]<>0 then dfs2(son[x],chain);
     59    i:=head[x];
     60    while i<>0 do
     61      begin
     62       y:=e[i].go;
     63       if (p[y]=0) and (y<>son[x]) then dfs2(y,y);
     64       i:=e[i].next;
     65      end;
     66  end;
     67 procedure pushup(k:longint);
     68  begin
     69     t[k].mx:=max(t[k<<1].mx,t[k<<1+1].mx);
     70     t[k].sum:=t[k<<1].sum+t[k<<1+1].sum;
     71  end;
     72 
     73 procedure build(k,x,y:longint);
     74  begin
     75    with t[k] do
     76     begin
     77      l:=x;r:=y;mid:=(l+r)>>1;
     78      if l=r then begin mx:=a[l];sum:=a[l];exit;end;
     79      build(k<<1,l,mid);build(k<<1+1,mid+1,r);
     80      pushup(k);
     81     end;
     82  end;
     83 procedure change(k,x,y:longint);
     84  begin
     85    with t[k] do
     86     begin
     87      if l=r then begin mx:=y;sum:=y;exit;end;
     88      if x<=mid then change(k<<1,x,y)
     89      else change(k<<1+1,x,y);
     90      pushup(k);
     91     end;
     92  end;
     93 
     94 function getmx(k,x,y:longint):longint;
     95  begin
     96    with t[k] do
     97     begin
     98      if (l=x) and (r=y) then exit(mx);
     99      if y<=mid then exit(getmx(k<<1,x,y))
    100      else if x>mid then exit(getmx(k<<1+1,x,y))
    101      else exit(max(getmx(k<<1,x,mid),getmx(k<<1+1,mid+1,y)));
    102     end;
    103  end;
    104 function getsum(k,x,y:longint):longint;
    105  begin
    106    with t[k] do
    107     begin
    108      if (l=x) and (r=y) then exit(sum);
    109      if y<=mid then exit(getsum(k<<1,x,y))
    110      else if x>mid then exit(getsum(k<<1+1,x,y))
    111      else exit(getsum(k<<1,x,mid)+getsum(k<<1+1,mid+1,y));
    112     end;
    113  end;
    114 
    115 procedure init;
    116  begin
    117    readln(n);
    118    for i:=1 to n-1 do begin readln(x,y);insert(x,y);insert(y,x);end;
    119    dep[1]:=1;
    120    dfs1(1);
    121    dfs2(1,1);
    122    for i:=1 to n do read(v[i]);
    123    for i:=1 to n do a[p[i]]:=v[i];
    124    build(1,1,n);
    125  end;
    126 procedure solvemx;
    127  begin
    128    ans:=-maxlongint;
    129    while ch<>' ' do read(ch);
    130    readln(x,y);
    131    while top[x]<>top[y] do
    132      begin
    133       if dep[top[x]]<dep[top[y]] then swap(x,y);
    134       ans:=max(ans,getmx(1,p[top[x]],p[x]));
    135       x:=fa[top[x]];
    136      end;
    137    if dep[x]>dep[y] then swap(x,y);
    138    ans:=max(ans,getmx(1,p[x],p[y]));
    139    writeln(ans);
    140  end;
    141 procedure solvesum;
    142  begin
    143    ans:=0;
    144    while ch<>' ' do read(ch);
    145    readln(x,y);
    146      while top[x]<>top[y] do
    147      begin
    148       if dep[top[x]]<dep[top[y]] then swap(x,y);
    149       inc(ans,getsum(1,p[top[x]],p[x]));
    150       x:=fa[top[x]];
    151      end;
    152    if dep[x]>dep[y] then swap(x,y);
    153    inc(ans,getsum(1,p[x],p[y]));
    154    writeln(ans);
    155  end;
    156 
    157 procedure main;
    158  begin
    159    readln(m);
    160    for i:=1 to m do
    161     begin
    162      read(ch);
    163      if ch='C' then
    164       begin
    165        while ch<>' ' do read(ch);readln(x,y);
    166        change(1,p[x],y);
    167       end
    168      else
    169       begin
    170        read(ch);
    171        if ch='M' then solvemx else solvesum;
    172        end;
    173     end;
    174  end;
    175 
    176 begin
    177   assign(input,'input.txt');assign(output,'output.txt');
    178   reset(input);rewrite(output);
    179   init;
    180   main;
    181   close(input);close(output);
    182 end.   
    View Code
     
  • 相关阅读:
    百度地图API显示多个标注点带百度样式信息检索窗口的代码
    百度地图API显示多个标注点并添加百度样式检索窗口
    log4j.xml 为什么要使用SLF4J而不是Log4J
    C++编程学习52个经典网站 强力推荐
    一些User-Agent
    outlook 2003配置连接exchange server 2010报错——无法完成此操作。 与 Microsoft Exchange Server 的连接不可用。 Outlook 必须联机或连接才可完成该操作
    postfix+dovecot邮箱服务器
    Java学习之InputStream中read()与read(byte[] b)
    Java Scoket之java.io.EOFException解决方案
    java.util.zip.GZIPInputStream.readUByte,Not in GZIP format错误处理
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3899155.html
Copyright © 2011-2022 走看看