题目链接:http://poj.org/problem?id=3468
题目很简短,连我这个四级考了二百多分的人读题都没什么压力。。。
思路:很简单的线段树成段更新。仿照hh大牛hdu1698的代码AC的。
///2014.6.1
///poj3468
#include <cstdio>
#include <algorithm>
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 111111;
int n,q;
long long col[maxn<<2];
long long sum[maxn<<2];
void PushUp(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m) {
if (col[rt]) {
col[rt<<1] += col[rt];
col[rt<<1|1] += col[rt];
sum[rt<<1] += (m - (m >> 1)) * col[rt];
sum[rt<<1|1] += (m >> 1) * col[rt];
col[rt] = 0;
}
}
void build(int l,int r,int rt) {
col[rt] = 0;
if (l == r){
scanf("%lld",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt) {
if (L <= l && r <= R) {
col[rt] += c;
sum[rt] += c * (r - l + 1);
return ;
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L , R , c , lson);
if (R > m) update(L , R , c , rson);
PushUp(rt);
}
long long query(int L,int R,int l,int r,int rt) {
if (L <= l && r <= R) {
return sum[rt];
}
PushDown(rt,r-l+1);
int m = (l + r) >> 1;
long long ret = 0;
if (L <= m) ret += query(L , R , lson);
if (R > m) ret += query(L , R , rson);
return ret;
}
int main() {
// freopen("in","r",stdin);
scanf("%d%d",&n,&q);
build(1,n,1);
char op[5];
int a,b,c;
while( q-- ){
scanf("%s",op);
if( op[0] == 'Q' ){
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1,n,1) );
}
else{
scanf("%d%d%d",&a,&b,&c);
update(a,b,c,1,n,1);
}
}
return 0;
}