线段树:优雅的分块暴力
区间修改(单点修改),区间查询
POJ3468
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
const int maxn = 1e6+10;
using namespace std;
typedef long long ll;
ll aa[maxn], ans;
struct node{
ll a, b, len;
ll sum;
ll lazy;
};
node tree[maxn*4];
void pushup(int rt){tree[rt].sum = tree[rt<<1].sum+tree[rt<<1|1].sum;return;}
int cnt =1;
void build(ll a, ll b, int num){
cnt = max(num, cnt);
tree[num].a = a;
tree[num].b = b;
tree[num].lazy = 0;
tree[num].len = (b-a+1);
if(a == b){tree[num].sum = aa[a];}
else{
int mid = (a+b)>>1;
build(a, mid, num<<1);
build(mid+1, b, (num<<1)+1);
pushup(num);
}
}
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].sum+=tree[rt<<1].len*tree[rt].lazy;
tree[rt<<1|1].sum+=tree[rt<<1|1].len*tree[rt].lazy;
tree[rt].lazy = 0;
}
}
/*345各加3,+6不是+9???*/
void query(ll a, ll b, int num){
if(a>tree[num].b||tree[num].a>b) return;
if(tree[num].a>=a&&tree[num].b<=b){
pushdown(num);
ans+=tree[num].sum;
return;
}
pushdown(num);
query(a, b, num<<1|1);
query(a, b, (num<<1));
pushup(num);
}
void add(ll a, ll b, ll val, int num){
if(a>tree[num].b||tree[num].a>b) return;
if(tree[num].a>=a&&tree[num].b<=b){
tree[num].sum+=tree[num].len*val;
tree[num].lazy+=val;
return ;
}
pushdown(num); //向下更新时先pushdown
add(a, b, val, num<<1);
add(a, b, val, num<<1|1);
pushup(num); //更新
}
int main(){
int n, m;
cin>>n>>m;
for(int i = 1; i <= n; i++){
scanf("%lld", &aa[i]);
}
build(1, n, 1);//从一开始建树
/*for(int i = 1; i <= cnt; i++){
printf("%d ;%d %d :sum : %d\n", i, tree[i].a, tree[i].b, tree[i].sum);
}*/
ll x, y, z;
char ch;
for(int i = 0; i < m; i++){
//scanf("%c %d%d\n", &ch, &x, &y);
cin>>ch>>x>>y;
if(ch == 'Q'){
ans = 0;
query(x, y, 1);
printf("%lld\n", ans);
//getchar();
}
else{
scanf("%lld\n", &z);
add(x, y, z, 1);
/* for(int i = 1; i <= cnt; i++){
printf("%d ;%d %d :sum : %d\n", i, tree[i].a, tree[i].b, tree[i].sum);
}*/
}
}
return 0;
}