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