您的位置:首页 > 其它

A Simple Problem with Integers POJ - 3468 线段树模板

2017-09-03 13:00 453 查看
题目链接:

POJ-3468

大意:

区间修改,区间求和。线段树模板题。

线段树与树状数组比较:

线段树的功能更强大,但树状数组的常数较小。

#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
using namespace std;
typedef long long ll;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0id3f3f3f3f
#define pb push_back
#define  pii pair<int,int>
//#define LOCAL
const int MAXN =1e5+10;
int n,a[MAXN],q;
struct node{
ll lazy,sum;
int l,r;
void update(ll val){
sum+=1LL*(r-l+1)*val;
lazy+=val;
}
}tree[4*MAXN];
void push_up(int id){
tree[id].sum=tree[id<<1].sum+tree[id<<1|1].sum;
}
void push_down(int id){
int lazyval=tree[id].lazy;
if(lazyval){
tree[id<<1].update(lazyval);
tree[id<<1|1].update(lazyval);
tree[id].lazy=0;
}
}
void build(int id,int l,int r){
tree[id].l=l,tree[id].r=r;
tree[id].sum=tree[id].lazy=0;
if(l==r){
tree[id].sum=a[l];
}else {
int mid=(l+r)/2;
build(id<<1,l,mid);
build(id<<1|1,mid+1,r);
push_up(id);
}
}
void update(int id,int l,int r,int val){
int L=tree[id].l,R=tree[id].r;
if(l<=L&&R<=r){
tree[id].update(val);
}else {
push_down(id);
int mid=(L+R)/2;
if(mid>=l) update(id<<1,l,r,val);
if(r>mid) update(id<<1|1,l,r,val);
push_up(id);
}
}
ll query(int id,int l,int r){
ll ans=0;
int L=tree[id].l,R=tree[id].r;
if(l<=L&&R<=r){
return tree[id].sum;
}else {
push_down(id);
int mid=(L+R)/2;
if(mid>=l) ans+=query(id<<1,l,r);
if(r>mid) ans+=query(id<<1|1,l,r);
push_up(id);
}
return ans;
}
int main(){
scanf("%d%d",&n,&q);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
build(1,1,n);//build(1,l,r)
for(int i=1;i<=q;i++){
int l,r,val;
char ch[2];
scanf("%s",ch);
if(ch[0]=='Q'){
scanf("%d%d",&l,&r);
printf("%lld\n",query(1,l,r));
}else {
scanf("%d%d%d",&l,&r,&val);
update(1,l,r,val);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  线段树 模板
相关文章推荐