线段树区间和
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树区间和相关的知识,希望对你有一定的参考价值。
区间和
做法:
节点个数设为4倍的区间长度
使用线段树模板就可,注意
a
,
b
≤
n
a,b \\leq n
a,b≤n,建树的区间需要是
[
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分)