题目地址:http://poj.org/problem?id=3468
线段树初学水题,就步多说了
区间求和,区间更新。
#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll (v<<1)
#define rr (v<<1|1)
#define tmid ((l+r)>>1)
using namespace std;
const int maxn=100004;
const int inf=-1000000005;
__int64 sum[maxn*4],num[maxn*4];
int s[maxn];
int n,m;
void make_tree(int l,int r,int v){
num[v]=0;
if(l==r){
sum[v]=s[l];
return;
}
make_tree(l,tmid,ll);
make_tree(tmid+1,r,rr);
sum[v]=sum[ll]+sum[rr];
}
void update(int x,int y,int z,int l,int r,int v){
sum[v]+=z*(y-x+1);
if(x<=l && r<=y){
num[v]+=z;
return;
}
if(x>tmid)
update(x,y,z,tmid+1,r,rr);
else if(y<=tmid)
update(x,y,z,l,tmid,ll);
else{
update(x,tmid,z,l,tmid,ll);
update(tmid+1,y,z,tmid+1,r,rr);
}
}
__int64 query(int x,int y,int l,int r,int v){
if(x<=l && r<=y)
return sum[v];
if(x>tmid)
return num[v]*(y-x+1)+query(x,y,tmid+1,r,rr);
if(y<=tmid)
return num[v]*(y-x+1)+query(x,y,l,tmid,ll);
return num[v]*(y-x+1)+query(x,tmid,l,tmid,ll)+query(tmid+1,y,tmid+1,r,rr);
}
int main(){
int i,j;
int x,y,z;
char op[2];
while(~scanf("%d%d",&n,&m)){
for(i=1;i<=n;i++)
scanf("%d",&s[i]);
make_tree(1,n,1);
while(m--){
scanf("%s",op);
if(op[0]=='Q'){
scanf("%d%d",&x,&y);
printf("%I64d\n",query(x,y,1,n,1));
}
else{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1,n,1);
}
}
}
return 0;
}