思路:线段树,节点区间的和由sum和add组成,更新:当区间正好匹配时就直接node[k].add += add,return,否则把和加在sum里,递归更新子区间。查找时:如果区间匹配就直接返回node[k].sum + (node[k].right - node[k].left + 1) * node[k].add,否则将和加在sum中,add向子区间传递。
/*************************************************************************
> File Name: inter.cpp
> Author: wangzhili
> Mail: wangstdio.h@gmail.com
> Created Time: 2014/2/27 星期四 14:16:52
************************************************************************/
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100005
class TreeNode
{
public:
int left;
int right;
int mid;
long long int sum;
long long int add;
};
TreeNode node[4*MAX];
void BuildTree(int k, int l, int r)
{
node[k].left = l;
node[k].right = r;
node[k].mid = (l + r) >> 1;
node[k].sum = 0;
node[k].add = 0;
if(l == r)
return ;
int mid = (l + r) >> 1;
BuildTree(k << 1, l, mid);
BuildTree(k << 1|1, mid+1, r);
}
void UpdateTree(int k, int l, int r, long long int add)
{
if(node[k].left == l && node[k].right == r)
{
node[k].add += add;
return ;
}
node[k].sum += (r-l+1) * add;
if(node[k].mid < l)
UpdateTree(k << 1|1, l, r, add);
else if(node[k].mid >= r)
UpdateTree(k << 1, l, r, add);
else
{
UpdateTree(k << 1, l, node[k].mid, add);
UpdateTree(k << 1|1, node[k].mid + 1, r, add);
}
}
long long int GetSum(int k, int l, int r)
{
if(node[k].left == l && node[k].right == r)
return node[k].sum + (node[k].right - node[k].left + 1) * node[k].add;
node[k << 1].add += node[k].add;
node[k << 1|1].add += node[k].add;
node[k].sum += (node[k].right - node[k].left + 1) * node[k].add;
node[k].add = 0;
if(node[k].mid < l)
return GetSum(k << 1|1, l, r);
else if(node[k].mid >= r)
return GetSum(k << 1, l, r);
else
return GetSum(k << 1, l, node[k].mid) + GetSum(k << 1|1, node[k].mid + 1, r);
}
int main(int argc, char const *argv[])
{
int n, i, m, l, r, num;
char str[2];
freopen("in.c", "r", stdin);
while(~scanf("%d%d", &n, &m))
{
BuildTree(1, 1, n);
for(i = 1; i <= n; i ++)
{
scanf("%d", &num);
UpdateTree(1, i, i, num);
}
for(i = 0; i < m; i ++)
{
scanf("%s", str);
if(str[0] == 'Q')
{
scanf("%d%d", &l, &r);
printf("%lld\n", GetSum(1, l, r));
}
else
{
scanf("%d%d%d", &l, &r, &num);
UpdateTree(1, l, r, num);
}
}
}
return 0;
}