线段树区间和

Posted 行码棋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树区间和相关的知识,希望对你有一定的参考价值。

区间和

做法:

节点个数设为4倍的区间长度
使用线段树模板就可,注意 a , b ≤ n a,b \\leq n a,bn,建树的区间需要是 [ 1 , n ] [1,n] [1,n]而不是 [ 1 , m ] [1,m] [1,m]

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5+5,M = 5e5+5;

int n,m;
int k,a,b;
struct node
{
	int l,r;
	ll sum;
}tr[N * 4];

void pushup(int u)
{
	tr[u].sum = tr[u<<1].sum + tr[u<<1|1].sum;
}
//建树,从u节点开始,建[l,r]区间的树
void build(int u,int l,int r)
{
	tr[u] = {l,r,0};//建树前先初始化
	if(l==r) return ;
	int mid = tr[u].l + tr[u].r >> 1;
	build(u<<1,l,mid),build(u<<1|1,mid+1,r);
}
//从u节点开始查询[l,r]区间的和
ll query(int u,int l,int r)
{
	if(tr[u].l>=l && tr[u].r <= r) return tr[u].sum;
	int mid = tr[u].l + tr[u].r >> 1;
	ll s = 0;
	if(l <= mid) s += query(u<<1,l,r);
	if(r > mid) s += query(u<<1|1,l,r);
	return s;
}
//从u节点开始,在x位置的值加上v
void modify(int u,int x,int v)
{
	if(tr[u].l==x && tr[u].r==x) tr[u].sum += v;
	else
	{
		int mid = tr[u].l + tr[u].r >> 1;
		if(x<=mid) modify(u<<1,x,v);
		else modify(u<<1|1,x,v);
		pushup(u);//向上更新操作
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	build(1,1,n);
	while(m--)
	{
		scanf("%d%d%d",&k,&a,&b);
		if(k) cout<<query(1,a,b)<<'\\n';
		else modify(1,a,b);
	}
	return 0;
}

以上是关于线段树区间和的主要内容,如果未能解决你的问题,请参考以下文章

CCF(除法):线段树区间修改(50分)+线段树点修改(100分)+线段树(100分)

线段树区间和

线段树

线段树维护区间最大子段和

数据结构 ---[实现 线段树(SegmentTree) ]

线段树区间修改区间求和