Description
You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is to ask for the sum of numbers in a given interval.
Input
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
Output
You need to answer all Q commands in order. One answer in a line.
Sample Input
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
Sample Output
55
9
15
HINT
The sums may exceed the range of 32-bit integers.
Source
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll read(){
ll x=(ll)0,f=(ll)1;char ch=getchar();
while (ch<'0' || ch>'9'){if (ch=='-') f=(ll)-1;ch=getchar();}
while (ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int
N=100005;
int n,q,a[N];
ll tree[N<<2],mark[N<<2];
void build(int id,int l,int r){
if (l==r){
tree[id]=a[l];
return;
}
int mid=(l+r)>>1;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
tree[id]=tree[id<<1]+tree[id<<1|1];
}
void update(int id,int l,int r,int gx,int gy,int num){
if (l==gx && r==gy){
mark[id]+=num;
tree[id]+=(ll)num*(r-l+1);
return;
}
int mid=(l+r)>>1;
mark[id<<1]+=mark[id];
mark[id<<1|1]+=mark[id];
tree[id<<1]+=(ll)mark[id]*(mid-l+1);
tree[id<<1|1]+=(ll)mark[id]*(r-mid);
mark[id]=(ll)0;
if (gy<=mid) update(id<<1,l,mid,gx,gy,num); else
if (gx>mid) update(id<<1|1,mid+1,r,gx,gy,num);
else{
update(id<<1,l,mid,gx,mid,num);
update(id<<1|1,mid+1,r,mid+1,gy,num);
}
tree[id]=tree[id<<1]+tree[id<<1|1];
}
ll query(int id,int l,int r,int gx,int gy){
if (gx<=l && gy>=r) return tree[id];
int mid=(l+r)>>1;
mark[id<<1]+=mark[id];
mark[id<<1|1]+=mark[id];
tree[id<<1]+=(ll)mark[id]*(mid-l+1);
tree[id<<1|1]+=(ll)mark[id]*(r-mid);
mark[id]=(ll)0;
if (gy<=mid) return query(id<<1,l,mid,gx,gy); else
if (gx>mid) return query(id<<1|1,mid+1,r,gx,gy); else
return query(id<<1,l,mid,gx,mid)+query(id<<1|1,mid+1,r,mid+1,gy);
}
int main() {
n=read(),q=read();
for (int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
while (q--){
char ts[2]; int x,y;
scanf("%s",ts);
if (ts[0]=='Q'){
x=read(),y=read();
printf("%lld\n",query(1,1,n,x,y));
} else{
ll z;
x=read(),y=read(),z=read();
update(1,1,n,x,y,z);
}
}
return 0;
}