区间修改,区间求值
1 const int N=100010; 2 ll a[N],sum[N],add[N]; 3 int L[N],R[N],pos[N]; 4 int n,m,ds; 5 6 void modify(int l,int r,ll k) 7 { 8 int p=pos[l],q=pos[r]; 9 if(p==q) 10 { 11 FOR(i,l,r) a[i]+=k; 12 sum[p]+=(r-l+1)*k; 13 return; 14 } 15 FOR(i,p+1,q-1) add[i]+=k; 16 FOR(i,l,R[p]) a[i]+=k; 17 sum[p]+=(R[p]-l+1)*k; 18 FOR(i,L[q],r) a[i]+=k; 19 sum[q]+=(r-L[q]+1)*k; 20 } 21 22 ll query(int l,int r) 23 { 24 int p=pos[l],q=pos[r]; 25 ll ans=0; 26 if(p==q) 27 { 28 FOR(i,l,r) ans+=a[i]; 29 ans+=add[p]*(r-l+1); 30 return ans; 31 } 32 FOR(i,p+1,q-1) 33 ans+=sum[i]+add[i]*(R[i]-L[i]+1); 34 FOR(i,l,R[p]) ans+=a[i]; 35 ans+=(R[p]-l+1)*add[p]; 36 FOR(i,L[q],r) ans+=a[i]; 37 ans+=(r-L[q]+1)*add[q]; 38 return ans; 39 } 40 41 int main() 42 { 43 scanf("%d%d",&n,&m); 44 FOR(i,1,n) scanf("%lld",&a[i]); 45 ds=sqrt(n); 46 FOR(i,1,ds) 47 L[i]=(i-1)*ds+1, 48 R[i]=i*ds; 49 if(R[ds]<n) ++ds,L[ds]=R[ds-1]+1,R[ds]=n; 50 FOR(i,1,ds) FOR(j,L[i],R[i]) pos[j]=i,sum[i]+=a[j]; 51 int opt,l,r;ll k; 52 while(m--) 53 { 54 scanf("%d%d%d",&opt,&l,&r); 55 if(opt==1) 56 { 57 scanf("%lld",&k); 58 modify(l,r,k); 59 } 60 else printf("%lld ",query(l,r)); 61 } 62 return 0; 63 }