题目链接:http://poj.org/problem?id=2528
区间增减模板题,不论是update还是query中都要进行下放标记。
#include <iostream>
#include <cstdio>
#define lson l, m, x<<1
#define rson m+1, r, x<<1|1
using namespace std;
typedef long long type;
const int INF = (1<<31)-1;
const int maxn =100000 + 10;
type sum[maxn << 2];
type delta[maxn << 2];
type a[maxn];
type n, m;
void pushUp(int x)
{
sum[x] = sum[x<<1] + sum[x<<1|1];
}
void pushDown(int x, int len)
{
if (delta[x])
{
delta[x<<1] += delta[x];
delta[x<<1|1] += delta[x];
sum[x<<1] += (len - (len >> 1)) * delta[x];
sum[x<<1|1] += (len >> 1) * delta[x];
delta[x] = 0;
}
}
void build(int l, int r, int x)
{
if(l == r)
{
sum[x] = a[l];
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushUp(x);
}
void update(int l, int r, int x, int L, int R, type C)
{
if (L <= l && r <= R)
{
sum[x] += C * (r-l+1);
delta[x] += C;
return ;
}
pushDown(x, r-l+1);
int m = (l + r) >> 1;
if (L <= m) update(lson, L, R, C);
if (R > m) update(rson, L, R, C);
pushUp(x);
}
type query(int l, int r, int x, int L, int R)
{
if (L <= l && r <= R)
{
return sum[x];
}
pushDown(x, r-l+1);
int m = (l + r) >> 1;
type ret = 0;
if (L <= m) ret += query(lson, L, R);
if (R > m) ret += query(rson, L, R);
return ret;
}
int main()
{
scanf("%d%d",&n, &m);
for (int i=0; i<n; i++) scanf("%I64dd",&a[i+1]);
getchar();
build(1, n, 1);
for (int i=0; i<m; i++)
{
char c;
scanf("%c",&c);
getchar();
if (c == 'C')
{
type a, b, c;
scanf("%d%d%I64dd", &a, &b, &c);
getchar();
update(1, n, 1, a, b, c);
}
else
{
type a, b;
scanf("%d%d", &a, &b);
getchar();
printf("%I64d\n", query(1, n, 1, a, b));
}
}
return 0;
}