zoukankan      html  css  js  c++  java
  • bzoj1558

    好题,初看以为只要差分然后维护相同的段数目
    但是请注意下面的情况
    2 3 5 8 9
     1 2 3 4 这显然答案是3而不是4
    因此我们还要再维护ld,rd表示左右单独的段长度
    和s表示不包括左右单独的段,中间部分最少划分成几个等差数列
    具体维护见程序,比较复杂,但其实不难
    这题还有一个坑爹的地方,我一开始忘开int64本地测数据竟然全能过
    但是交上去就WA……感人肺腑

      1 type node=record
      2        l,r:int64;
      3        ld,rd,s:longint;
      4      end;
      5 
      6 var tree:array[0..100010*4] of node;
      7     lazy:array[0..100010*4] of int64;
      8     a:array[0..100010] of longint;
      9     n,m,i,x0,y0,x,y,p,q:longint;
     10     z:int64;
     11     ans:node;
     12     ch:char;
     13 
     14 procedure update(var a:node;x,y:node);
     15   begin
     16     a.l:=x.l;
     17     a.r:=y.r;
     18     a.ld:=x.ld;
     19     if x.s=0 then  //x.s=0说明左部分全是单独的(没有连续出现2个及以上的)
     20     begin
     21       if x.r<>y.l then inc(a.ld,y.ld)
     22       else dec(a.ld);
     23     end;
     24     a.rd:=y.rd;
     25     if y.s=0 then
     26     begin
     27       if x.r<>y.l then inc(a.rd,x.rd)
     28       else dec(a.rd);
     29     end;
     30     a.s:=x.s+y.s;
     31     if x.s=0 then   //以下请自行理解
     32     begin
     33       if x.r=y.l then
     34       begin
     35         if y.s=0 then inc(a.s)
     36         else if (y.ld>0) then inc(a.s,(y.ld-1) shr 1+1);
     37       end;
     38     end
     39     else if x.rd>0 then
     40     begin
     41       if x.r=y.l then
     42       begin
     43         inc(a.s,(x.rd-1) shr 1);
     44         if y.s=0 then inc(a.s)
     45         else if (y.ld>0) then inc(a.s,(y.ld-1) shr 1+1);
     46       end
     47       else if y.s>0 then
     48         inc(a.s,(x.rd+y.ld) shr 1);
     49     end
     50     else begin
     51       if x.r=y.l then
     52       begin
     53         if (y.s>0) and (y.ld>0) then inc(a.s,(y.ld-1) shr 1);
     54         if (y.s>0) and (y.ld=0) then dec(a.s);
     55       end
     56       else if (y.s>0) and (y.ld>0) then inc(a.s,y.ld shr 1);
     57     end;
     58   end;
     59 
     60 procedure push(i:longint);
     61   begin
     62     inc(lazy[i*2],lazy[i]);
     63     inc(tree[i*2].l,lazy[i]);
     64     inc(tree[i*2].r,lazy[i]);
     65     inc(lazy[i*2+1],lazy[i]);
     66     inc(tree[i*2+1].l,lazy[i]);
     67     inc(tree[i*2+1].r,lazy[i]);
     68     lazy[i]:=0;
     69   end;
     70 
     71 procedure build(i,l,r:longint);
     72   var m:longint;
     73   begin
     74     if l=r then
     75     begin
     76       tree[i].l:=a[l+1]-a[l];
     77       tree[i].r:=a[l+1]-a[l];
     78       tree[i].ld:=1;
     79       tree[i].rd:=1;
     80     end
     81     else begin
     82       m:=(l+r) shr 1;
     83       build(i*2,l,m);
     84       build(i*2+1,m+1,r);
     85       update(tree[i],tree[i*2],tree[i*2+1]);
     86     end;
     87   end;
     88 
     89 procedure add(i,l,r:longint);
     90   var m:longint;
     91   begin
     92     if (x<=l) and (y>=r) then
     93     begin
     94       inc(tree[i].l,z);
     95       inc(tree[i].r,z);
     96       lazy[i]:=lazy[i]+z;
     97     end
     98     else begin
     99       if lazy[i]<>0 then push(i);
    100       m:=(l+r) shr 1;
    101       if x<=m then add(i*2,l,m);
    102       if y>m then add(i*2+1,m+1,r);
    103       update(tree[i],tree[i*2],tree[i*2+1]);
    104     end;
    105   end;
    106 
    107 function ask(i,l,r:longint):node;
    108   var s,s1,s2:node;
    109       m:longint;
    110   begin
    111     if (x<=l) and (y>=r) then exit(tree[i])
    112     else begin
    113       m:=(l+r) shr 1;
    114       if lazy[i]<>0 then push(i);
    115       if y<=m then exit(ask(i*2,l,m));
    116       if x>m then exit(ask(i*2+1,m+1,r));
    117       s1:=ask(i*2,l,m);
    118       s2:=ask(i*2+1,m+1,r);
    119       update(s,s1,s2);
    120       exit(s);
    121     end;
    122   end;
    123 
    124 begin
    125   readln(n);
    126   for i:=1 to n do
    127     readln(a[i]);
    128   dec(n);
    129   build(1,1,n);
    130   readln(m);
    131   for i:=1 to m do
    132   begin
    133     read(ch);
    134     if ch='A' then
    135     begin
    136       readln(x0,y0,p,q);
    137       if x0>1 then //修改要分三种情况
    138       begin
    139         x:=x0-1; y:=x0-1; z:=p;  
    140         add(1,1,n);
    141       end;
    142       if y0<=n then
    143       begin
    144         x:=y0; y:=y0; z:=-int64(p)-int64(y0-x0)*int64(q);
    145         add(1,1,n);
    146       end;
    147       if x0<y0 then
    148       begin
    149         x:=x0; y:=y0-1; z:=q;
    150         add(1,1,n);
    151       end;
    152     end
    153     else begin
    154       readln(x,y);
    155       if y=x then writeln(1)
    156       else begin
    157         dec(y);
    158         ans:=ask(1,1,n);
    159         if ans.s=0 then writeln((y-x+3) shr 1) //全是单独的可以直接算出来
    160         else writeln(ans.s+(ans.ld+1) shr 1+(ans.rd+1) shr 1);
    161       end;
    162     end;
    163   end;
    164 end.
    View Code
  • 相关阅读:
    hdoj 2803 The MAX【简单规律题】
    hdoj 2579 Dating with girls(2)【三重数组标记去重】
    hdoj 1495 非常可乐【bfs隐式图】
    poj 1149 PIGS【最大流经典建图】
    poj 3281 Dining【拆点网络流】
    hdoj 3572 Task Schedule【建立超级源点超级汇点】
    hdoj 1532 Drainage Ditches【最大流模板题】
    poj 1459 Power Network【建立超级源点,超级汇点】
    hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】
    hdoj 1012 u Calculate e
  • 原文地址:https://www.cnblogs.com/phile/p/4472981.html
Copyright © 2011-2022 走看看