zoukankan      html  css  js  c++  java
  • 【BZOJ4034】T2(树链剖分)

    题意:

     有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个

    操作,分为三种:
    操作 1 :把某个节点 x 的点权增加 a 。
    操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
    操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

    对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不


    会超过 10^6。
     
    思路:

    因为以X为根中的子树分成了一条条重链,而他们的编号是连续的。

    所以我们可以在DFS2时找到以x为根时它的子树在线段树中的最大编号mx[x]。

    然后就是裸地区间修改和求和。

      1 var t:array[1..500000]of record
      2                           a,s:int64;
      3                          end;
      4     head,vet,next,top,tid,mx,fa,size,a,son,flag,dep,id:array[0..200000]of longint;
      5     n,m,i,x,y,tot,time,ch:longint;
      6 
      7 procedure add(a,b:longint);
      8 begin
      9  inc(tot);
     10  next[tot]:=head[a];
     11  vet[tot]:=b;
     12  head[a]:=tot;
     13 end;
     14 
     15 function max(x,y:longint):longint;
     16 begin
     17  if x>y then exit(x);
     18  exit(y);
     19 end;
     20 
     21 procedure dfs1(u:longint);
     22 var e,maxsize,v:longint;
     23 begin
     24  flag[u]:=1; size[u]:=1;
     25  e:=head[u]; son[u]:=0; maxsize:=0;
     26  while e<>0 do
     27  begin
     28   v:=vet[e];
     29   if flag[v]=0 then
     30   begin
     31    fa[v]:=u; dep[v]:=dep[u]+1;
     32    dfs1(v);
     33    size[u]:=size[u]+size[v];
     34    if size[v]>maxsize then
     35    begin
     36     maxsize:=size[v];
     37     son[u]:=v;
     38    end;
     39   end;
     40   e:=next[e];
     41  end;
     42 end;
     43 
     44 procedure dfs2(u,ance:longint);
     45 var e,v:longint;
     46 begin
     47  flag[u]:=1; inc(time); tid[u]:=time; id[time]:=u; top[u]:=ance;
     48  mx[u]:=time;
     49  if son[u]>0 then
     50  begin
     51   dfs2(son[u],ance);
     52   mx[u]:=max(mx[u],mx[son[u]]);
     53  end;
     54  e:=head[u];
     55  while e<>0 do
     56  begin
     57   v:=vet[e];
     58   if flag[v]=0 then
     59   begin
     60    dfs2(v,v);
     61    mx[u]:=max(mx[u],mx[v]);
     62   end;
     63   e:=next[e];
     64  end;
     65 end;
     66 
     67 procedure build(l,r,p:longint);
     68 var mid:longint;
     69 begin
     70  if l=r then
     71  begin
     72   t[p].s:=a[id[l]];
     73   exit;
     74  end;
     75  mid:=(l+r)>>1;
     76  build(l,mid,p<<1);
     77  build(mid+1,r,p<<1+1);
     78  t[p].s:=t[p<<1].s+t[p<<1+1].s;
     79 end;
     80 
     81 procedure update(l,r,x,y:longint;v:int64;p:longint);
     82 var mid:longint;
     83 begin
     84  if (l>=x)and(r<=y) then
     85  begin
     86   t[p].a:=t[p].a+v;
     87   t[p].s:=t[p].s+v*(r-l+1);
     88   exit;
     89  end;
     90  mid:=(l+r)>>1;
     91  t[p<<1].a:=t[p<<1].a+t[p].a;
     92  t[p<<1+1].a:=t[p<<1+1].a+t[p].a;
     93  t[p<<1].s:=t[p<<1].s+(mid-l+1)*t[p].a;
     94  t[p<<1+1].s:=t[p<<1+1].s+(r-mid)*t[p].a;
     95  t[p].a:=0;
     96  if x<=mid then update(l,mid,x,y,v,p<<1);
     97  if y>mid then update(mid+1,r,x,y,v,p<<1+1);
     98  t[p].s:=t[p<<1].s+t[p<<1+1].s;
     99 end;
    100 
    101 function query(l,r,x,y,p:longint):int64;
    102 var mid:longint;
    103     tt:int64;
    104 begin
    105  if (l>=x)and(r<=y) then exit(t[p].s);
    106  mid:=(l+r)>>1;
    107  t[p<<1].a:=t[p<<1].a+t[p].a;
    108  t[p<<1+1].a:=t[p<<1+1].a+t[p].a;
    109  t[p<<1].s:=t[p<<1].s+(mid-l+1)*t[p].a;
    110  t[p<<1+1].s:=t[p<<1+1].s+(r-mid)*t[p].a;
    111  t[p].a:=0;
    112  tt:=0;
    113  if x<=mid then tt:=tt+query(l,mid,x,y,p<<1);
    114  if y>mid then tt:=tt+query(mid+1,r,x,y,p<<1+1);
    115  exit(tt);
    116 end;
    117 
    118 function ask(x:longint):int64;
    119 var t:int64;
    120 begin
    121  t:=0;
    122  while top[x]<>1 do
    123  begin
    124   t:=t+query(1,n,tid[top[x]],tid[x],1);
    125   x:=fa[top[x]];
    126  end;
    127  t:=t+query(1,n,1,tid[x],1);
    128  exit(t);
    129 end;
    130 
    131 begin
    132  assign(input,'bzoj4034.in'); reset(input);
    133  assign(output,'bzoj4034.out'); rewrite(output);
    134  readln(n,m);
    135  for i:=1 to n do read(a[i]);
    136  for i:=1 to n-1 do
    137  begin
    138   readln(x,y);
    139   add(x,y);
    140   add(y,x);
    141  end;
    142  dfs1(1);
    143  fillchar(flag,sizeof(flag),0);
    144  dfs2(1,1);
    145  build(1,n,1);
    146 
    147  for i:=1 to m do
    148  begin
    149   read(ch);
    150   case ch of
    151    1:
    152    begin
    153     read(x,y);
    154     update(1,n,tid[x],tid[x],y,1);
    155    end;
    156    2:
    157    begin
    158     read(x,y);
    159     update(1,n,tid[x],mx[x],y,1);
    160    end;
    161    3:
    162    begin
    163     read(x);
    164     writeln(ask(x));
    165    end;
    166   end;
    167  end;
    168  close(input);
    169  close(output);
    170 end.
     
  • 相关阅读:
    他山之石____集合框架__【List,Set,Map之间的区别】
    集合框架__【泛型】
    集合框架__【Set集合】【HashSet】【TreeSet】
    模式串匹配,KMP算法——HDU1686
    模式串匹配,KMP算法——HDU1711
    网络最大流——POJ
    网络最大流——HDU
    拓扑排序——CodeForces-645D
    二分图染色,二分图匹配——HDU
    二分图匹配,最小点覆盖——POJ
  • 原文地址:https://www.cnblogs.com/myx12345/p/6111156.html
Copyright © 2011-2022 走看看