题目链接:http://poj.org/problem?id=3468
题意:给你N个数,然后有M个操作。有两种类型的操作,(1)“Ca b c”,表示将区间[a,b]里的数加上c。(2)“Q a b”,表示查询区间[a,b]的数的和
区间维护线段树模板题
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 100005;
int Size, n, m, w, h, num;
struct line
{
int l,r;
long long sum, add;
}node[4 * maxn];
void PushUp(int root)
{
node[root].sum = node[root << 1].sum + node[root << 1 | 1].sum;
}
void PushDown(int root, int m)
{
if(node[root].add)
{
node[root << 1].add += node[root].add;
node[root << 1 | 1].add += node[root].add;
node[root << 1].sum += node[root].add * (m - (m>>1));
node[root << 1 | 1].sum += node[root].add * (m>>1);
node[root].add = 0;
}
}
void init()
{
int i;
for(n = 1; n < h; n <<= 1);
for(i = n; i < 2 * n; i++)
{
node[i].l = node[i].r = i - n + 1;
if(i - n < h)
scanf("%lld", &node[i].sum);
else
node[i].sum = 0;
node[i].add = 0;
}
for(i = n - 1; i > 0; i--)
{
node[i].l = node[2*i].l;
node[i].r = node[2*i+1].r;
PushUp(i);
node[i].add = 0;
}
}
void update(int l, int r, int c, int root)
{
if(node[root].l == l && node[root].r == r)
{
node[root].sum += (__int64)c * (r - l + 1);
node[root].add += c;
return ;
}
if(node[root].r == node[root].l)
{
return ;
}
PushDown(root, node[root].r - node[root].l + 1);
int mid = (node[root].l + node[root].r) / 2;
if(r <= mid) update(l, r , c, root<<1);
else if(l > mid) update(l, r , c, root<<1|1);
else
{
update(l, mid, c, root<<1);
update(mid + 1, r, c, root<<1|1);
}
PushUp(root);
}
long long query(int l, int r, int root)
{
if(l == node[root].l && r == node[root].r)
{
return node[root].sum;
}
PushDown(root, node[root].r - node[root].l + 1);
int m = (node[root].l + node[root].r) >> 1;
__int64 res = 0;
if(r <= m) res += query(l, r, root << 1);
else if(l > m) res += query(l, r, root << 1 | 1);
else
{
res += query(l, m, root << 1);
res += query(m + 1, r, root << 1 | 1);
}
return res;
}
int main()
{
while(~scanf("%d %d", &h, &num))
{
init();
for(int i = 0; i < num; i++)
{
char s[3];
scanf("%s", s);
if(s[0] == 'Q')
{
int l, r;
scanf("%d %d", &l, &r);
cout << query(l, r, 1) << endl;
}
else
{
int l, r, c;
scanf("%d %d %d", &l, &r, &c);
update(l, r, c, 1);
}
}
}
return 0;
}