您的位置:首页 > 其它

2016夏季练习——线段树

2016-08-15 23:39 267 查看
来源:POJ3468

成段更新

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson rt<<1
#define rson rt<<1|1
using namespace std;
typedef long long LL;
const int MAXN = 111111;
LL tree[MAXN<<2];
LL lazy[MAXN<<2];
int dd;
int n,q;
char ch[5];
int x,y;
void pushup(int rt){
tree[rt] = tree[lson] + tree[rson];
}
void pushdown(int rt,int m){
if(lazy[rt]){
tree[lson] += lazy[rt]*(m-(m>>1));
tree[rson] += lazy[rt]*(m>>1);
lazy[rson] += lazy[rt];
lazy[lson] += lazy[rt];
lazy[rt] = 0;
}
}
void build(int rt,int l,int r){
lazy[rt] = 0 ;
if(l==r){
scanf("%I64d",&tree[rt]);
return ;
}
int mid = (l+r)>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(rt);
}
void update(int rt,int l,int r,int left,int right,int data){
if(left<=l && r<=right){
tree[rt] += (LL)(r-l+1)*data;
lazy[rt] += data;
return ;
}
pushdown(rt,r-l+1);
int mid = (l+r)>>1;
if(left<=mid) update(lson,l,mid,left,right,data);
if(right>mid) update(rson,mid+1,r,left,right,data);
pushup(rt);
}
LL query(int rt,int l,int r,int left,int right){
if(left<=l && r<=right) {
return tree[rt];
}
pushdown(rt,r-l+1);
int mid = (l+r)>>1;
LL ans = 0;
if(left<=mid) ans+=query(lson,l,mid,left,right);
if(right>mid) ans+=query(rson,mid+1,r,left,right);
return ans;
}
int main(){
scanf("%d%d",&n,&q);
//for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
//getchar();
while(q--){
scanf("%s",ch);
if(ch[0] == 'Q'){
scanf("%d%d",&x,&y);
printf("%I64d\n",query(1,1,n,x,y));
}
if(ch[0] == 'C'){
scanf("%d%d",&x,&y);
scanf("%d",&dd);
update(1,1,n,x,y,dd);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: