【数据结构模板】线段树(区间修改,区间查询)

本文介绍了一种使用线段树实现区间更新和查询的方法。该方法能够在对数时间内完成区间元素的增量更新及求和查询操作,适用于解决大规模数据集上的动态区间问题。文章详细解释了线段树的构建、更新和查询过程,并通过具体代码示例展示了如何高效地实现这些功能。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;
#define maxn 100005
ll a[maxn],tree[maxn<<2],b[maxn<<2];
int n,t;

ll ls(ll p){
	return p<<1;
} 

ll rs(ll p){
	return p<<1|1;
}

void push_up(ll p){
	tree[p]=tree[ls(p)]+tree[rs(p)];
}

void build(ll p,ll l,ll r){
	if(l==r) {tree[p]=a[l];return;}//
	
	ll m=(l+r)>>1;
	build(ls(p),l,m);
	build(rs(p),m+1,r);
	
	push_up(p);
}


void f(ll p,ll l,ll r,ll k){
	b[p]+=k;
	tree[p]+=(r-l+1)*k;
}
void push_down(ll p,ll l,ll r){
	ll m=(l+r)>>1;
	f(ls(p),l,m,b[p]);
	f(rs(p),m+1,r,b[p]);
	b[p]=0;//clear
}

void update(ll nl,ll nr,ll l,ll r,ll p,ll k){
	if(nl<=l && r<=nr){
		tree[p]+=(r-l+1)*k;
		b[p]+=k;
		return;
	}
	
	push_down(p,l,r);
	
	ll m=(l+r)>>1;
	if(nl<=m) update(nl,nr,l,m,ls(p),k);
	if(nr>m) update(nl,nr,m+1,r,rs(p),k);
	push_up(p);//
}

ll query(ll qx,ll qy,ll l,ll r,ll p){
	ll res=0;
	if(qx<=l && qy>=r) return tree[p];
	
	push_down(p,l,r);
	ll m=(l+r)>>1;
	if(qx<=m) res+=query(qx,qy,l,m,ls(p));
	if(qy>m) res+=query(qx,qy,m+1,r,rs(p));
	return res;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>t;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(t--){
		int pd;
		cin>>pd;
		if(pd&1){
			ll x,y,k;
			cin>>x>>y>>k;
			update(x,y,1,n,1,k);
		}
		else{
			ll x,y;
			cin>>x>>y;
			cout<<query(x,y,1,n,1)<<endl;
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值