題目大意
給定一個長度爲n的序列, 求m組詢問
C l r d 代表把區間l-r的數加上d
Q l r 代表求區間l, r的和
樣例
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
代碼
#include <iostream>
#include <cstring>
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 100010;
typedef long long ll;
struct Tree{
int l, r;
ll sum, lazy;
};
Tree tree[N * 4];
int a[N];
int n, m;
void pushdown(int node)
{
if(tree[node].lazy)
{
int l = tree[node].l;
int r = tree[node].r;
tree[node << 1].lazy += tree[node].lazy;
tree[node << 1 | 1].lazy += tree[node].lazy;
int mid = (l + r) >> 1;
tree[node << 1].sum += tree[node].lazy * (mid - l + 1);
tree[node << 1 | 1].sum += tree[node].lazy * (r - mid);
tree[node].lazy = 0;
}
}
void pushup(int node)
{
tree[node].sum = tree[node << 1].sum + tree[node << 1 | 1].sum;
}
void build(int node, int l, int r)
{
tree[node].l = l;
tree[node].r = r;
if(l == r)
{
tree[node].sum = a[l];
return;
}
int mid = (l + r) >> 1;
build(node << 1, l, mid);
build(node << 1 | 1, mid + 1, r);
pushup(node);
}
void update(int node, int l, int r, int d)
{
if(tree[node].l >= l && tree[node].r <= r)
{
tree[node].sum += (ll)d * (tree[node].r - tree[node].l + 1);
tree[node].lazy += d;
return;
}
int x = tree[node].l;
int y = tree[node].r;
int mid = (x + y) >> 1;
pushdown(node);
if(l <= mid)
update(node << 1, l, r, d);
if(r > mid)
update(node << 1 | 1, l, r, d);
pushup(node);
}
ll query(int node, int l, int r)
{
if(tree[node].l >= l && tree[node].r <= r)
return tree[node].sum;
pushdown(node);
int mid = (tree[node].l + tree[node].r) >> 1;
ll ans = 0;
if(l <= mid)
ans += query(node << 1, l, r);
if(r > mid)
ans += query(node << 1 | 1, l, r);
return ans;
}
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 s[2];
int l, r;
scanf("%s%d%d", s, &l, &r);
if(*s == 'C')
{
int d;
scanf("%d", &d);
update(1, l, r, d);
}
else
printf("%lld\n", query(1, l, r));
}
return 0;
}