分块模板
#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<stack> #include<set> #include<map> #include<vector> #include<iomanip> #include<bitset> using namespace std; // #define ll long long #define ull unsigned long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) #define sqr(a) (a)*(a) #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)) ll qp(ll a,ll b,ll mod){ ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t; } struct DOT{ll x;ll y;}; inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} const int dx[4]={0,0,-1,1}; const int dy[4]={1,-1,0,0}; const int inf=0x3f3f3f3f; const ll Linf=0x3f3f3f3f3f3f3f3f; const ll mod=1e9+7;; const int maxn=1e5+34; ll a[maxn],sum[maxn],add[maxn]; int L[maxn],R[maxn]; //块i的左右端点 int pos[maxn]; //块所属 int n,m,t; void init(){ t=sqrt(n); for(int i=1;i<=t;i++){ L[i]=(i-1)*t+1; R[i]=i*t; } if(R[t]<n){t++;L[t]=R[t-1]+1,R[t]=n;} for(int i=1;i<=t;i++) for(int j=L[i];j<=R[i];j++){ pos[j]=i; sum[i]+=a[j]; } } void update(int l,int r,ll d){ int p=pos[l],q=pos[r]; if(p==q){ for(int i=l;i<=r;i++)a[i]+=d; sum[p]+=d*(r-l+1); }else{ for(int i=p+1;i<=q-1;i++)add[i]+=d; for(int i=l;i<=R[p];i++)a[i]+=d; sum[p]+=d*(R[p]-l+1); for(int i=L[q];i<=r;i++)a[i]+=d; sum[q]+=d*(r-L[q]+1); } } ll query(int l,int r){ int p=pos[l],q=pos[r]; ll ans=0; if(p==q){ for(int i=l;i<=r;i++)ans+=a[i]; ans+=add[p]*(r-l+1); }else{ for(int i=p+1;i<=q-1;i++){ ans+=sum[i]+add[i]*(R[i]-L[i]+1); } for(int i=l;i<=R[p];i++)ans+=a[i]; ans+=add[p]*(R[p]-l+1); for(int i=L[q];i<=r;i++)ans+=a[i]; ans+=add[q]*(r-L[q]+1); } return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)scanf("%lld",&a[i]); init(); while(m--){ char op[3]; int l,r,d; scanf("%s%d%d",op,&l,&r); if(op[0]=='C'){ scanf("%d",&d); update(l,r,d); }else{ printf("%lld\n",query(l,r)); } } }