思路比较奇怪,是二阶差分。详见代码:
二阶差分到底是不是正确的???
#include<bits/stdc++.h>
//#pragma GCC optimize(3)
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define MAXN 100010
//#define int long long
#define ll long long
#define mdI int mid=(l+r)>>1
inline int qread(){
char c=getchar();int num=0,f=1;
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) num=num*10+c-'0';
return num*f;
}
#define rep(a,b,c) for(int a=b;a<=c;a++)
bool FLA;
int n;
ll A[MAXN],D[MAXN],E1[MAXN];
struct node{
int ans[2],I[2],L,R,sz;
//ans[0]I[0]->[l,r] ans[1]I[1]->[l+1,r]
node(){sz=ans[0]=ans[1]=I[0]=I[1]=0;}
node(int l,int r,int s):L(l),R(r),sz(s){ans[0]=ans[1]=I[0]=I[1]=0;}
node operator+(const node&b)const{
node c(L,b.R,sz+b.sz);
if(I[0]==R+1){c.ans[0]=ans[0]+b.ans[0];c.I[0]=b.I[0];}
else{c.ans[0]=ans[0]+b.ans[1];c.I[0]=b.I[1];}
if(I[1]==R+1){c.ans[1]=ans[1]+b.ans[0];c.I[1]=b.I[0];}
else{c.ans[1]=ans[1]+b.ans[1];c.I[1]=b.I[1];}
return c;
}
};
node seg[MAXN<<2];
#define ls(x) x<<1
#define rs(x) (x<<1)|1
void pushup(int x){seg[x]=seg[ls(x)]+seg[rs(x)];}
void build(int x,int l,int r){
if(l==r){
seg[x]=node(l,r,1);
seg[x].I[1]=l+1;
if(E1[l]!=0){seg[x].I[0]=l+2,seg[x].ans[0]=1;}
else{seg[x].I[0]=l+1,seg[x].ans[0]=0;}
return;
}mdI;
build(ls(x),l,mid);build(rs(x),mid+1,r);
pushup(x);
}
void update(int x,int l,int r,int p,int v1){
if(l==r){
seg[x].I[1]=l+1;
if(E1[l]!=0){seg[x].I[0]=l+2,seg[x].ans[0]=1;}
else{seg[x].I[0]=l+1,seg[x].ans[0]=0;}return;
}mdI;
if(p<=mid){update(ls(x),l,mid,p,v1);}
else{update(rs(x),mid+1,r,p,v1);}
pushup(x);
}
node query(int x,int l,int r,int ql,int qr){
if(l==ql&&r==qr){return seg[x];}mdI;
if(qr<=mid){return query(ls(x),l,mid,ql,qr);}
else if(ql>mid){return query(rs(x),mid+1,r,ql,qr);}
else{return query(ls(x),l,mid,ql,mid)+query(rs(x),mid+1,r,mid+1,qr);}
}
bool FLB;
signed main(){
cerr<<((&FLB)-(&FLA))/1024.0/1024<<endl;
cin>>n;
rep(i,1,n){A[i]=qread();D[i]=A[i]-A[i-1];}
rep(i,1,n){E1[i]=D[i]-D[i-1];}
build(1,1,n);
int m;cin>>m;
while(m--){
char op[10];int l,r;
scanf("%s",&op);l=qread(),r=qread();
if(op[0]=='A'){
int a=qread(),b=qread();
E1[l]+=a;
if(l+1<=n)E1[l+1]+=b-a;
if(r+1<=n)E1[r+1]-=(a+b*(r-l+1));
if(r+2<=n)E1[r+2]+=(a+b*(r-l));
update(1,1,n,l,a);
if(l+1<=n)update(1,1,n,l+1,b-a);
if(r+1<=n)update(1,1,n,r+1,-(a+b*(r-l+1)));
if(r+2<=n)update(1,1,n,r+2,(a+b*(r-l)));
}
else{
int nans=query(1,1,n,l+2,r).ans[0]+1;
printf("%d\n",nans);
}
}
}
/*
二阶差分
1 2 4 8
1 2 4
*/