http://poj.org/problem?id=3468
题意:将区间上的所有数加上一个数,询问区间上数的总和。使用线段数的区间更新,lazy思想降低时间复杂度。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
struct node{
int l, r;
LL lazy, value;
int mid(){
return (l + r) >> 1;
}
}tree[N << 2];
void pushdown(int rt){
if(tree[rt].lazy){
tree[rt << 1].lazy += tree[rt].lazy;
tree[rt << 1 | 1].lazy += tree[rt].lazy;
tree[rt << 1].value += (tree[rt << 1].r - tree[rt << 1].l + 1) * tree[rt].lazy;
tree[rt << 1 | 1].value += (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l + 1) * tree[rt].lazy;
tree[rt].lazy = 0;
}
}
void buildtree(int l, int r, int rt){
tree[rt].l = l;
tree[rt].r = r;
tree[rt].lazy = 0;
if(l == r){
scanf("%lld",&tree[rt].value);
return;
}
int mid = tree[rt].mid();
buildtree(l, mid, rt << 1);
buildtree(mid+1, r, rt << 1 | 1);
tree[rt].value = tree[rt << 1].value + tree[rt << 1 | 1].value;
}
void update(int l, int r, int rt, int key){
if(tree[rt].l >= l && tree[rt].r <= r){///lazy value 同时更新,保证询问时两个都是正确的
tree[rt].lazy += key;
tree[rt].value += (tree[rt].r - tree[rt].l + 1) * key;
return;
}
pushdown(rt);
int mid = tree[rt].mid();
if(r <= mid) update(l, r, rt << 1, key);
else if(l > mid) update(l, r, rt << 1 | 1, key);
else update(l, mid, rt << 1,key), update(mid+1, r, rt << 1 | 1, key);
tree[rt].value = tree[rt << 1].value + tree[rt << 1 | 1].value;
}
LL query(int l, int r, int rt){
if(tree[rt].l >= l && tree[rt].r <= r)
return tree[rt].value;
pushdown(rt);
int mid = tree[rt].mid();
LL ret = 0;
if(r <= mid) ret = query(l, r, rt << 1);
else if(l > mid) ret = query(l, r, rt << 1 | 1);
else ret = query(l, mid, rt << 1) + query(mid+1, r, rt << 1 | 1);
tree[rt].value = tree[rt << 1].value + tree[rt << 1 | 1].value;
return ret;
}
int main(){
// freopen("in.txt", "r", stdin);
int m,n;
while(scanf("%d%d",&m,&n) == 2){
buildtree(1, m, 1);
char str[10];
int a,b,x;
for(int i=0; i<n; i++){
scanf("%s",str);
if(str[0] == 'Q'){
scanf("%d%d",&a,&b);
printf("%lld\n",query(a,b,1));
}
else{
scanf("%d%d%d",&a,&b,&x);
update(a,b,1,x);
}
}
}
return 0;
}