zoukankan      html  css  js  c++  java
  • bzoj4127

    肯定是树链剖分+线段树,关键是怎么维护

    绝对值和这个东西显然不能简单的合并标记

    因为对于负数,加之后绝对值和是变小的

    那我们考虑对负数和非负数数分别维护

    下面的问题就是经过操作如果负数变成了正数怎么办

    注意每次加的都是正数,这意味着这样的变化最多发生n次,

    每个数发生这种变化,我们就用push到底即可,这样最多nlogn的

    所以我们只要在维护一个区间最大负数即可

      1 const inf=10000000000000;
      2 type node=record
      3        po,next:longint;
      4      end;
      5      link=record
      6        s0,s1,mx:int64;
      7        s:longint;
      8      end;
      9 
     10 var tree:array[0..100010*4] of link;
     11     lazy:array[0..100010*4] of int64;
     12     e:array[0..100010*2] of node;
     13     top,fa,a,b,c,d,p,s:array[0..100010] of longint;
     14     t,i,x,y,ch,z,len,n,m:longint;
     15 
     16 function max(a,b:int64):int64;
     17   begin
     18     if a>b then exit(a) else exit(b);
     19   end;
     20 
     21 procedure swap(var a,b:longint);
     22   var c:longint;
     23   begin
     24     c:=a;
     25     a:=b;
     26     b:=c;
     27   end;
     28 
     29 procedure add(x,y:longint);
     30   begin
     31     inc(len);
     32     e[len].po:=y;
     33     e[len].next:=p[x];
     34     p[x]:=len;
     35   end;
     36 
     37 procedure dfs1(x:longint);
     38   var i,y:longint;
     39   begin
     40     i:=p[x];
     41     s[x]:=1;
     42     while i<>0 do
     43     begin
     44       y:=e[i].po;
     45       if s[y]=0 then
     46       begin
     47         fa[y]:=x;
     48         d[y]:=d[x]+1;
     49         dfs1(y);
     50         s[x]:=s[x]+s[y];
     51       end;
     52       i:=e[i].next;
     53     end;
     54   end;
     55 
     56 procedure dfs2(x:longint);
     57   var q,i,y:longint;
     58   begin
     59     inc(t);
     60     c[x]:=t;
     61     b[t]:=x;
     62     i:=p[x];
     63     q:=0;
     64     while i<>0 do
     65     begin
     66       y:=e[i].po;
     67       if c[y]=0 then
     68         if s[y]>s[q] then q:=y;
     69       i:=e[i].next;
     70     end;
     71     if q<>0 then
     72     begin
     73       top[q]:=top[x];
     74       dfs2(q);
     75     end;
     76     i:=p[x];
     77     while i<>0 do
     78     begin
     79       y:=e[i].po;
     80       if c[y]=0 then
     81       begin
     82         top[y]:=y;
     83         dfs2(y);
     84       end;
     85       i:=e[i].next;
     86     end;
     87   end;
     88 
     89 procedure update(i:longint);
     90   begin
     91     tree[i].s0:=tree[i*2].s0+tree[i*2+1].s0;
     92     tree[i].s1:=tree[i*2].s1+tree[i*2+1].s1;
     93     tree[i].s:=tree[i*2].s+tree[i*2+1].s;
     94     tree[i].mx:=max(tree[i*2].mx,tree[i*2+1].mx);
     95   end;
     96 
     97 procedure build(i,l,r:longint);
     98   var m:longint;
     99   begin
    100     if l=r then
    101     begin
    102       if a[b[l]]>=0 then
    103       begin
    104         tree[i].s0:=a[b[l]];
    105         tree[i].s:=1;
    106         tree[i].mx:=-inf;
    107       end
    108       else begin
    109         tree[i].s1:=a[b[l]];
    110         tree[i].mx:=a[b[l]];
    111       end;
    112     end
    113     else begin
    114       m:=(l+r) shr 1;
    115       build(i*2,l,m);
    116       build(i*2+1,m+1,r);
    117       update(i);
    118     end;
    119   end;
    120 
    121 procedure modi(i,len:longint; z:int64);
    122   begin
    123     inc(lazy[i],z);
    124     inc(tree[i].mx,z);
    125     inc(tree[i].s0,int64(tree[i].s)*z);
    126     inc(tree[i].s1,int64(len-tree[i].s)*z);
    127   end;
    128 
    129 procedure push(i,l,r:longint);
    130   var m:longint;
    131   begin
    132     m:=(l+r) shr 1;
    133     modi(i*2,m-l+1,lazy[i]);
    134     modi(i*2+1,r-m,lazy[i]);
    135     lazy[i]:=0;
    136   end;
    137 
    138 procedure down(i,l,r:longint);
    139   var m:longint;
    140   begin
    141     if l=r then
    142     begin
    143       tree[i].s0:=tree[i].mx;
    144       tree[i].s:=1;
    145       tree[i].mx:=-inf;
    146       tree[i].s1:=0;
    147     end
    148     else begin
    149       m:=(l+r) shr 1;
    150       if lazy[i]<>0 then push(i,l,r);
    151       if tree[i*2].mx>=0 then down(i*2,l,m);
    152       if tree[i*2+1].mx>=0 then down(i*2+1,m+1,r);
    153       update(i);
    154     end;
    155   end;
    156 
    157 procedure ins(i,l,r,x,y:longint);
    158   var m:longint;
    159   begin
    160     if (x<=l) and (y>=r) then
    161     begin
    162       if tree[i].mx+z>=0 then
    163       begin
    164         inc(lazy[i],z);
    165         inc(tree[i].mx,z);
    166         down(i,l,r);
    167       end
    168       else modi(i,r-l+1,z);
    169     end
    170     else begin
    171       if lazy[i]<>0 then push(i,l,r);
    172       m:=(l+r) shr 1;
    173       if x<=m then ins(i*2,l,m,x,y);
    174       if y>m then ins(i*2+1,m+1,r,x,y);
    175       update(i);
    176     end;
    177   end;
    178 
    179 function get(i,l,r,x,y:longint):int64;
    180   var m:longint;
    181       s:int64;
    182 
    183   begin
    184     if (x<=l) and (y>=r) then exit(tree[i].s0+abs(tree[i].s1))
    185     else begin
    186       if lazy[i]<>0 then push(i,l,r);
    187       m:=(l+r) shr 1;
    188       s:=0;
    189       if x<=m then s:=s+get(i*2,l,m,x,y);
    190       if y>m then s:=s+get(i*2+1,m+1,r,x,y);
    191       exit(s);
    192     end;
    193   end;
    194 
    195 procedure work(x,y:longint);
    196   var f1,f2:longint;
    197   begin
    198     f1:=top[x];
    199     f2:=top[y];
    200     while f1<>f2 do
    201     begin
    202       if d[f1]>=d[f2] then
    203       begin
    204         ins(1,1,n,c[f1],c[x]);
    205         x:=fa[f1];
    206         f1:=top[x];
    207       end
    208       else begin
    209         ins(1,1,n,c[f2],c[y]);
    210         y:=fa[f2];
    211         f2:=top[y];
    212       end;
    213     end;
    214     if c[x]>c[y] then swap(x,y);
    215     ins(1,1,n,c[x],c[y]);
    216   end;
    217 
    218 function ask(x,y:longint):int64;
    219   var f1,f2:longint;
    220   begin
    221     ask:=0;
    222     f1:=top[x];
    223     f2:=top[y];
    224     while f1<>f2 do
    225     begin
    226       if d[f1]>=d[f2] then
    227       begin
    228         ask:=ask+get(1,1,n,c[f1],c[x]);
    229         x:=fa[f1];
    230         f1:=top[x];
    231       end
    232       else begin
    233         ask:=ask+get(1,1,n,c[f2],c[y]);
    234         y:=fa[f2];
    235         f2:=top[y];
    236       end;
    237     end;
    238     if c[x]>c[y] then swap(x,y);
    239     ask:=ask+get(1,1,n,c[x],c[y]);
    240   end;
    241 
    242 
    243 begin
    244   readln(n,m);
    245   for i:=1 to n do
    246     read(a[i]);
    247   for i:=1 to n-1 do
    248   begin
    249     readln(x,y);
    250     add(x,y);
    251     add(y,x);
    252   end;
    253   dfs1(1);
    254   top[1]:=1;
    255   dfs2(1);
    256   build(1,1,n);
    257   for i:=1 to m do
    258   begin
    259     read(ch,x,y);
    260     if ch=1 then
    261     begin
    262       readln(z);
    263       work(x,y);
    264     end
    265     else begin
    266       readln;
    267       writeln(ask(x,y));
    268     end;
    269   end;
    270 end.
    View Code
  • 相关阅读:
    抽丝剥茧,在实践中深入学习QTP
    项目实践精解:ASP.NET应用开发
    Oracle 10g宝典(第2版)
    PHP5应用实例详解
    项目实践精解:C#核心技术应用开发
    乐于分享、善待他人
    《jBPM4工作流应用开发指南》这本书
    IT项目的面向对象分析设计、开发及管理
    SPSS 17.0中文版常用功能与应用实例精讲
    TSQL 访问远程数据库并对其数据表进行操作
  • 原文地址:https://www.cnblogs.com/phile/p/4665476.html
Copyright © 2011-2022 走看看