依然是模板,原版来自hh大神
题目链接:http://poj.org/problem?id=3468
lazy的思想还是蛮有用的吧。。不只是线段树
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
typedef long long ll;
using namespace std;
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
const int maxn = 100050;
ll lazy[maxn<<2];
ll sum[maxn<<2];
void PushUp(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(ll rt,ll m) {
if (lazy[rt]) {
lazy[rt<<1] += lazy[rt];
lazy[rt<<1|1] += lazy[rt];
sum[rt<<1] += (m - (m >> 1)) * lazy[rt];
sum[rt<<1|1] += (m >> 1) * lazy[rt];
lazy[rt] = 0;
}
}
void build(ll l,ll r,ll rt) {
lazy[rt] = 0;
if (l == r) {
scanf("%I64d",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(ll L,ll R,ll c,ll l,ll r,ll rt) {
if (L <= l && r <= R) {
lazy[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);
}
ll query(ll L,ll R,ll l,ll r,ll rt)
{
if(L<=l && R>=r) return sum[rt];
PushDown(rt, r-l+1);
int m = (l+r) >>1;
ll ret=0;
if(L<=m) ret += query(L,R,lson);
if(R>m) ret += query(L,R,rson);
return ret;
}
int main() {
freopen("input.txt","r",stdin);
int N,Q;
memset(lazy,0,sizeof(lazy));
memset(sum,0,sizeof(sum));
scanf("%d%d",&N,&Q);
build(1,N,1);
//cout<<N<<" "<<Q<<endl;
while(Q--)
{
char op[2];
ll a,b,c;
scanf("%s",op);
//cout<<op<<endl;
if(op[0] == 'Q'){
scanf("%I64d%I64d",&a,&b);
//cout<<a<<" "<<b<<endl;
printf("%I64d\n",query(a,b,1,N,1));
}
else{
scanf("%I64d%I64d%I64d",&a,&b,&c);
update(a,b,c,1,N,1);
}
}
return 0;
}