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
  • 相关阅读:
    Web后门工具WeBaCoo
    苹果内存取证工具volafox
    PlayMaker GUI的Normalized
    Arduino可穿戴教程之第一个程序——选择端口(三)
    缩略图信息提取工具vinetto
    jquery的defer
    toDo
    瀑布流案例
    js基本知识6
    js基本知识5
  • 原文地址:https://www.cnblogs.com/phile/p/4472981.html
Copyright © 2011-2022 走看看