通过差分可以玩区间:
bi=ai-a(i-1)
查询时考虑位置对答案的贡献 推导一下
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 typedef long long ll; 7 const int N=1e5; 8 9 ll n,a[N],b[N],c1[N],c2[N]; 10 11 //basic 12 inline int lowbit(int x){return x&-x;} 13 ll sum(ll *c,int x){ 14 ll ret=0; 15 for(;x>0;x-=lowbit(x)) ret+=c[x]; 16 return ret; 17 } 18 ll query(ll *c,int l,int r){ 19 return sum(c,r)-sum(c,l-1); 20 } 21 void addPoint(ll *c,int x,ll v){ 22 for(;x<=n;x+=lowbit(x)) c[x]+=v; 23 } 24 void build(ll *c,ll *a,ll n){ 25 for(int i=1;i<=n;i++){ 26 c[i]+=a[i]; 27 if(i+lowbit(i)<=n) 28 c[i+lowbit(i)]+=c[i]; //!!c[i] or while 29 } 30 } 31 32 //interval-interval 33 void initB(ll *b,ll *a){ 34 b[1]=a[1]; 35 for(int i=2;i<=n;i++) b[i]=a[i]-a[i-1]; 36 } 37 void addRange(int l,int r,ll v){ 38 addPoint(c1,l,v); addPoint(c2,l,v*l); 39 addPoint(c1,r+1,-v); addPoint(c2,r+1,-v*(r+1)); 40 } 41 ll sumRange(int l,int r){ 42 return query(c1,1,l)*(r-l+1)+ query(c1,l+1,r)*(r+1) -query(c2,l+1,r); 43 } 44 45 int t,l,r; 46 ll v; 47 int main(){ 48 49 //freopen("in.txt","r",stdin); 50 //freopen("1.txt","w",stdout); 51 52 cin>>n>>t; 53 for(int i=1;i<=n;i++) cin>>a[i]; 54 // for(int i=1;i<=n;i++){ 55 // addRange(i,i,a[i]); 56 // } 57 58 initB(b,a); 59 build(c1,b,n); 60 for(int i=1;i<=n;i++) b[i]*=i; 61 build(c2,b,n); 62 63 while(t--){ 64 int flag; 65 cin>>flag; 66 if(flag==1){ 67 cin>>l>>r; 68 cout<<sumRange(l,r)<<" "; 69 }else{ 70 cin>>l>>r>>v; 71 addRange(l,r,v); 72 cout<<sumRange(l,r)<<" "; 73 } 74 } 75 }