Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 133448 | Accepted: 41395 | |
Case Time Limit: 2000MS |
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
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
Source
#include <iostream>
#include <cstdio>
using namespace std;
const int mn = 100005;
struct node
{
int l, r;
long long s, lazy;
} t[8 * mn];
void build(int i, int l, int r)
{
t[i].l = l, t[i].r = r;
t[i].lazy = 0;
if (l == r)
{
scanf("%lld", &t[i].s);
return;
}
int m = (l + r) / 2;
build(2 * i, l, m);
build(2 * i + 1, m + 1, r);
t[i].s = t[2 * i].s + t[2 * i + 1].s;
return;
}
void pushdown(int i, int l, int r)
{
int m = (l + r) / 2;
t[2 * i].lazy += t[i].lazy;
t[2 * i + 1].lazy += t[i].lazy; /// 标记下沉给子节点
t[2 * i].s += t[i].lazy * (m - l + 1);
t[2 * i + 1].s += t[i].lazy * (r - m); /// 子节点sum += 下沉的标记 * 区间大小
t[i].lazy = 0; /// 父节点标记清零
return;
}
void add(int i, int l, int r, long long c)
{
if (l == t[i].l && r == t[i].r)
{
t[i].lazy += c; /// 标记该节点
t[i].s += c * (r - l + 1); /// 更新该节点sum
return;
}
pushdown(i, t[i].l, t[i].r); /// lazy标记下沉
int m = (t[i].l + t[i].r) / 2;
if (r <= m)
add(2 * i, l, r, c);
else if (l > m)
add(2 * i + 1, l, r, c);
else
{
add(2 * i, l, m, c);
add(2 * i + 1, m + 1, r, c);
} /// 更新子节点
t[i].s = t[2 * i].s + t[2 * i + 1].s; /// 更新父节点sum
return;
}
long long query(int i, int l, int r)
{
if (l == t[i].l && r == t[i].r)
return t[i].s;
pushdown(i, t[i].l, t[i].r); /// 途经区间标记下沉
int m = (t[i].l + t[i].r) / 2;
if (r <= m)
return query(2 * i, l, r);
else if (l > m)
return query(2 * i + 1, l, r);
else
return query(2 * i, l, m) + query(2 * i + 1, m + 1, r);
}
int main()
{
int n, q;
scanf("%d %d", &n, &q);
build(1, 1, n);
while (q--)
{
char ch[5];
scanf("%s", ch);
if (ch[0] == 'C')
{
int a, b;
long long c;
scanf("%d %d %lld", &a, &b, &c);
add(1, a, b, c);
}
else if (ch[0] == 'Q')
{
int a, b;
scanf("%d %d", &a, &b);
printf("%lld\n", query(1, a, b));
}
}
return 0;
}