题目:http://poj.org/problem?id=3468
给出N个整数,进行M次操作,C a b c 表示给区间[a, b]中的每一个数加上c, Q a b 表示询问区间[a, b] 的和
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#define ll long long int
using namespace std;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 7;
ll st[MAXN << 2], tmp[MAXN << 2];
int N, Q;
void push_up(int root)
{
st[root] = st[root << 1] + st[root << 1 | 1];
}
void push_down(int root, int len)
{
if(tmp[root])
{
tmp[root << 1] += tmp[root];
tmp[root << 1 | 1] += tmp[root];
st[root << 1] += tmp[root] * (len - len / 2);
st[root << 1 | 1] += tmp[root] * (len / 2);
tmp[root] = 0;
}
}
void build(int root, int l, int r)
{
tmp[root] = 0;
if(l == r)
{
scanf("%lld", &st[root]);
return ;
}
int mid = l + (r - l) / 2;
build(root << 1, l, mid);
build(root << 1 | 1, mid + 1, r);
push_up(root);
}
void add(int root, int l, int r, int add_l, int add_r, int val)
{
if(add_l <= l && add_r >= r)
{
tmp[root] += (ll)val;
st[root] += (ll)val*(r - l + 1);
return ;
}
int mid = l + (r - l) / 2;
push_down(root, r - l + 1);
if(add_l <= mid) add(root << 1, l, mid, add_l, add_r, val);
if(add_r > mid) add(root << 1 | 1, mid + 1, r, add_l, add_r, val);
push_up(root);
}
ll query(int root, int l, int r, int ql, int qr)
{
if(ql <= l && qr >= r)
{
return st[root];
}
int mid = l + (r - l) / 2;
push_down(root, r - l + 1);
ll ans = 0;
if(ql <= mid) ans += query(root << 1, l, mid, ql, qr);
if(qr > mid) ans += query(root << 1 | 1, mid + 1, r, ql, qr);
return ans;
}
int main()
{
scanf("%d %d", &N, &Q);
build(1, 1, N);
char op; int a, b, c;
for(int i = 0; i < Q; i++)
{
scanf(" %c %d %d", &op, &a, &b);
if(op == 'Q')
{
printf("%lld\n", query(1, 1, N, a, b));
}
else if(op == 'C')
{
scanf("%d", &c);
add(1, 1, N, a, b, c);
}
}
return 0;
}