好题,初看以为只要差分然后维护相同的段数目
但是请注意下面的情况
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

 

posted on 2015-02-25 19:34  acphile  阅读(243)  评论(0编辑  收藏  举报