zoukankan      html  css  js  c++  java
  • ZJ2008树的统计(树链剖分)

    type node1=record
         go,next:longint;end;
         node2=record
         l,r,mx,sum:longint;end;
    var i,x,y,n,q,tmp,cnt,sz,code:longint;
        ch,st:string;
        fa:array[0..30001,0..15] of longint;
        v,deep,son,head,pl,belong,vis:array[0..30001] of longint;
        e:array[0..60001] of node1;
        t:array[0..100001] of node2;
    procedure insert(x,y:longint);
     begin
     inc(cnt);e[cnt].go:=y;e[cnt].next:=head[x];head[x]:=cnt;
     inc(cnt);e[cnt].go:=x;e[cnt].next:=head[y];head[y]:=cnt;
     end;
    procedure dfs1(x:longint);
     var i,j:longint;
     begin
     son[x]:=1;vis[x]:=1;
     for i:=1 to 14 do
      begin
      if deep[x]<(1<<i) then break;
      fa[x,i]:=fa[fa[x,i-1],i-1];
      end;
     i:=head[x];
     while i<>0 do
      begin
      j:=e[i].go;
      if vis[j]=0 then
       begin
       deep[j]:=deep[x]+1;
       fa[j,0]:=x;
       dfs1(j);
       inc(son[x],son[j]);
       end;
      i:=e[i].next;
      end;
     end;
    procedure dfs2(x,chain:longint);
     var i,j,k:longint;
     begin
     k:=0;inc(sz);
     pl[x]:=sz;belong[x]:=chain;
     i:=head[x];
     while i<>0 do
      begin
      j:=e[i].go;
      if (deep[j]>deep[x]) and (son[j]>son[k]) then k:=j;
      i:=e[i].next;
      end;
     if k=0 then exit;
     dfs2(k,chain);
     i:=head[x];
     while i<>0 do
      begin
      j:=e[i].go;
      if (deep[j]>deep[x]) and (k<>j) then
       dfs2(j,j);
      i:=e[i].next;
      end;
     end;
    function lca(x,y:longint):longint;
     var i,tmp:longint;
     begin
     if deep[x]<deep[y] then begin tmp:=x;x:=y;y:=tmp;end;
     tmp:=deep[x]-deep[y];
     for i:=0 to 14 do
      if (tmp and (1<<i)<>0) then x:=fa[x,i];
     for i:=14 downto 0 do
      if fa[x,i]<>fa[y,i] then
       begin
       x:=fa[x,i];y:=fa[y,i];
       end;
     if x=y then exit(x) else exit(fa[x,0]);
     end;
    procedure build(x,y,k:longint);
     var mid:longint;
     begin
     with t[k] do
      begin
      l:=x;r:=y;
      if l=r then exit;
      mid:=(l+r)>>1;
      build(l,mid,k<<1);
      build(mid+1,r,k<<1+1);
      end;
     end;
     function max(x,y:longint):longint;
      begin
      if x>y then exit(x) else exit(y);
      end;
    procedure change(x,y,k:longint);
     var mid:longint;
     begin
     with t[k] do
      begin
      if l=r then
       begin sum:=y;mx:=y;exit;end;
      mid:=(l+r)>>1;
      if x<=mid then change(x,y,k<<1)
      else change(x,y,k<<1+1);
      sum:=t[k<<1].sum+t[k<<1+1].sum;
      mx:=max(t[k<<1].mx,t[k<<1+1].mx);
      end;
     end;
    function getsum(x,y,k:longint):longint;
     var mid:longint;
     begin
     with t[k] do
      begin
      if (l=x) and (r=y) then exit(sum);
      mid:=(l+r)>>1;
      if x>mid then exit(getsum(x,y,k<<1+1))
      else if y<=mid then exit((getsum(x,y,k<<1)))
      else exit(getsum(x,mid,k<<1)+getsum(mid+1,y,k<<1+1));
      end;
     end;
    function getmx(x,y,k:longint):longint;
     var mid:longint;
     begin
     with t[k] do
      begin
      if (l=x) and (r=y) then exit(mx);
      mid:=(l+r)>>1;
      if x>mid then exit(getmx(x,y,k<<1+1))
      else if y<=mid then exit(getmx(x,y,k<<1))
      else exit(max(getmx(x,mid,k<<1),getmx(mid+1,y,k<<1+1)));
      end;
     end;
    function solvesum(x,y:longint):longint;
     var sum:longint;
     begin
     sum:=0;
     while belong[x]<>belong[y] do
      begin
      inc(sum,getsum(pl[belong[x]],pl[x],1));
      x:=fa[belong[x],0];
      end;
     inc(sum,getsum(pl[y],pl[x],1));
     exit(sum);
     end;
    function solvemx(x,y:longint):longint;
     var mx:longint;
     begin
     mx:=-maxlongint;
     while belong[x]<>belong[y] do
      begin
      mx:=max(mx,getmx(pl[belong[x]],pl[x],1));
      x:=fa[belong[x],0];
      end;
     mx:=max(mx,getmx(pl[y],pl[x],1));
     exit(mx);
     end;
    procedure init;
     begin
     readln(n);
     for i:=1 to n-1 do
      begin
      readln(x,y);insert(x,y);
      end;
     for i:=1 to n do read(v[i]);
     end;
    procedure solve;
     begin
     build(1,n,1);
     for i:=1 to n do change(pl[i],v[i],1);
     readln(q);
     for i:=1 to q do
      begin
      readln(st);
      ch:=copy(st,1,pos(' ',st)-1);
      delete(st,1,pos(' ',st));
      val(copy(st,1,pos(' ',st)-1),x,code);
      delete(st,1,pos(' ',st));
      val(st,y,code);
      case ch of
      'CHANGE':begin
               v[x]:=y;
               change(pl[x],y,1);
               end;
      'QMAX':begin
             tmp:=lca(x,y);
             writeln(max(solvemx(x,tmp),solvemx(y,tmp)));
             end;
       else begin
             tmp:=lca(x,y);
             writeln(solvesum(x,tmp)+solvesum(y,tmp)-v[tmp]);
            end;
       end;
      end;
     end;
    begin
     init;
     dfs1(1);
     dfs2(1,1);
     solve;
    end.
    
    
                          

    作为以后的模版!

  • 相关阅读:
    c#除掉字符串最后一个字符几种方法
    DateTime.Compare(t1,t2)比较两个日期大小
    图片如何存入数据库
    C#文本文件(.txt)读写
    【番外篇】ASP.NET MVC快速入门之免费jQuery控件库(MVC5+EF6)
    【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)
    【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6)
    【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6)
    【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)
    总结用CoreText绘制文本时遇到的问题以及解决办法
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3762955.html
Copyright © 2011-2022 走看看