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
10 5 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
4 55 9 15
Hint
The sums may exceed the range of 32-bit integers.
线段树区间更新求和板子,需要用到延迟标记。
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
struct SegmentTree{
int l, r;
long long sum, add;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define sum(x) tree[x].sum
#define add(x) tree[x].add
}tree[100010*4];
int a[100010],n, m;
void build(int p, int l, int r){
l(p) = l, r(p) = r;
if(l == r){ sum(p) = a[l]; return ;}
int mid = (l+r)/2;
build(p*2,l,mid);
build(p*2+1, mid+1, r);
sum(p) = sum(p*2) + sum(p*2+1);
}
void spread(int p){
if(add(p)){
sum(p*2) += add(p)*(r(p*2) - l(p*2)+1);
sum(p*2+1) += add(p)*(r(p*2+1) - l(p*2+1)+1);
add(p*2) += add(p);
add(p*2+1) += add(p);
add(p) = 0;
}
}
void change(int p, int l, int r, int d){
if(l <= l(p) && r >= r(p)){
sum(p) += (long long)d * (r(p)-l(p)+1);
add(p) += d;
return;
}
spread(p);
int mid = (l(p)+r(p))/2;
if(l <= mid) change(p*2, l, r, d);
if(r > mid) change(p*2+1, l, r, d);
sum(p) = sum(p*2) + sum(p*2+1);
}
long long ask(int p, int l, int r){
if(l <=l(p) && r >= r(p)) return sum(p);
spread(p);
int mid = (l(p)+r(p))/2;
long long val = 0;
if(l <= mid) val += ask(p*2, l, r);
if(r > mid) val += ask(p*2+1, l, r);
return val;
}
int main(){
scanf("%d %d",&n, &m);
for(int i=1; i<=n; i++) scanf("%d", &a[i]);
build(1, 1, n);
while(m--){
char op[2];
int l, r, d;
scanf("%s%d%d",op, &l, &r);
if(op[0] == 'C'){
scanf("%d", &d);
change(1, l, r, d);
}
else printf("%lld\n", ask(1, l, r));
}
return 0;
}