线段树+区间增量累加法lnc 区间更新,区间查询~
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; typedef long long ll; const int maxn=1e6+14; struct node { int l; int r; ll sum; ll lnc; }segTree[maxn*4]; int num[maxn]; void build (int i,int l,int r) { segTree[i].l=l; segTree[i].r=r; segTree[i].lnc=0; if (l==r) { segTree[i].sum=num[l]; return; } int mid=(l+r)>>1; build (i<<1,l,mid); build (i<<1|1,mid+1,r); segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum; } void add (int i,int a,int b,ll c) { if (segTree[i].l==a&&segTree[i].r==b) { segTree[i].lnc+=c; return; } segTree[i].sum+=c*(b-a+1); int mid=(segTree[i].l+segTree[i].r)>>1; if (b<=mid) add(i<<1,a,b,c); else if (a>mid) add(i<<1|1,a,b,c); else { add(i<<1,a,mid,c); add(i<<1|1,mid+1,b,c); } } ll query (int i,int a,int b) { if (segTree[i].l==a&&segTree[i].r==b) { return segTree[i].sum+(b-a+1)*segTree[i].lnc; } segTree[i].sum+=(segTree[i].r-segTree[i].l+1)*segTree[i].lnc; int mid=(segTree[i].l+segTree[i].r)>>1; add(i<<1,segTree[i].l,mid,segTree[i].lnc); add(i<<1|1,mid+1,segTree[i].r,segTree[i].lnc); segTree[i].lnc=0; if (b<=mid) return query(i<<1,a,b); else if (a>mid) return query(i<<1|1,a,b); else return query(i<<1,a,mid)+query(i<<1|1,mid+1,b); } int main () { int n; int q; int a,b,c; char ch; while (~scanf("%d %d",&n,&q)) { for (int i=1;i<=n;i++) scanf ("%d",&num[i]); build (1,1,n); for (int i=1;i<=q;i++) { cin>>ch; if (ch=='C') scanf ("%d %d %d",&a,&b,&c),add(1,a,b,c); else { scanf ("%d %d",&a,&b); printf ("%lld ",query(1,a,b)); } } } return 0; }