您的位置:首页 > 其它

POJ 3468 A Simple Problem with Integers(线段树区间更新,模板题,求区间和)

2013-11-07 20:52 561 查看
#include <iostream>
#include <stdio.h>
#include <string.h>
#define lson rt<<1,L,mid
#define rson rt<<1|1,mid+1,R

using namespace std;
const int maxn=100005;
int n,q;
long long num[maxn];
struct Node{
long long sum,add;
bool lazy;
}tree[maxn<<2];

void pushUp(int rt){
tree[rt].sum=tree[rt<<1].sum+tree[rt<<1|1].sum;
}
void pushDown(int rt,int m){
if(tree[rt].lazy){
tree[rt<<1].add+=tree[rt].add;
tree[rt<<1|1].add+=tree[rt].add;
tree[rt<<1].sum+=(m-m/2)*tree[rt].add;  //是加上父亲的add
tree[rt<<1|1].sum+=m/2*tree[rt].add;
tree[rt<<1].lazy=tree[rt<<1|1].lazy=true;
tree[rt].add=0;
tree[rt].lazy=false;
}
}
void build(int rt,int L,int R){
if(L==R){
tree[rt].sum=num[L];
tree[rt].add=0;
tree[rt].lazy=false;
return ;
}
int mid=(L+R)>>1;
build(lson);
build(rson);
pushUp(rt);
}

void update(int rt,int L,int R,int l,int r,long long val){
if(l<=L&&R<=r){
tree[rt].sum+=(R-L+1)*val;
tree[rt].add+=val;
tree[rt].lazy=true;
return;
}
pushDown(rt,R-L+1);
int mid=(L+R)>>1;
if(l<=mid)
update(lson,l,r,val);
if(r>mid)
update(rson,l,r,val);
pushUp(rt);
}

long long query(int rt,int L,int R,int l,int r){
long long ret=0;
if(l<=L&&R<=r){
return tree[rt].sum;
}
pushDown(rt,R-L+1);  //额,好吧,忘记这里也要初始化了
int mid=(L+R)>>1;
if(l<=mid)
ret+=query(lson,l,r);
if(r>mid)
ret+=query(rson,l,r);
return ret;
}
int main()
{
int a,b;
long long c; //c用int也能AC,用long long是防止当(R-L+1)*c的时候超出int范围
char str[4];
long long ans;
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++)
scanf("%I64d",&num[i]);
build(1,1,n);
for(int i=1;i<=q;i++){
scanf("%s",str);
if(str[0]=='C'){
scanf("%d%d%I64d",&a,&b,&c);
update(1,1,n,a,b,c);
}
else{
scanf("%d%d",&a,&b);
ans=query(1,1,n,a,b);
printf("%I64d\n",ans);
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐