线段树就是一颗二叉树,
在二叉树上建立区间;
所以第一个板子是如何建立一颗树,我喜欢直接建,比较暴力;
宏定义虽然慢,但是很方便;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
PS:宏实际是调用文本,所以宏定义中的字母变量必须到时候与函数中的调用字母一致,不然会报错<strong>void Build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&MAX[rt]);
return;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
}</strong>
单节点更新:既将某坐标的值修改为某个值;
<strong>void Update(int p,int add,int l,int r,int rt)
{
if(l==r)
{
MAX[rt]=add;
return;
}
int mid=(l+r)>>1;
if(p<=mid)
Update(p,add,lson);
else
Update(p,add,rson);
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
</strong>
最大值查询
<strong>void Build(int l,int r,int rt)//*一颗最大值树
{
if(l==r)
{
scanf("%d",&MAX[rt]);
return;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
return MAX[rt];
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret=max(ret,Query(L,R,lson));
if(R>m) ret=max(ret,Query(L,R,rson));
return ret;
}</strong>
最小值查询
<strong>void Build(int l,int r,int rt)//* 一颗最小值树
{
if(l==r)
{
scanf("%d",&MAX[rt]);
return;
}
int m=(l+r)>>1;
Build(lson);
Build(rson);
MAX[rt]=min(MAX[rt<<1],MAX[rt<<1|1]);
}
int Query(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)
return MAX[rt];
int m=(l+r)>>1;
int ret=0;
if(L<=m) ret=min(ret,Query(L,R,lson));
if(R>m) ret=min(ret,Query(L,R,rson));
return ret;
}
</strong>
查询区间和
要更新区间和,就必须把当前值储存起来,其中可以用黑科技 inline 函数
#include <bits/stdc++.h>
using namespace std ;
#define N 500005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
int sum[N<<2];
inline void PushPlus(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l, int r, int rt)
{
if(l == r)
{
scanf("%d", &sum[rt]);
return ;
}
int m = ( l + r )>>1;
build(lson);
build(rson);
PushPlus(rt);
}
int search(int L ,int R ,int l , int r , int rt)
{
int ans = 0 ;
if(L<=l&&R>=r)
{
return sum[rt];
}
int m = (l+r)>>1;
if(L<=m) ans += search(L,R,lson);
if(R>m) ans += search(L,R,rson);
return ans ;
}
动态更新区间点
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define root 1 , N , 1
#define LL long long
const int maxn = 111111;
LL add[maxn<<2];
LL sum[maxn<<2];
void PushUp(int rt) {
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
}
void PushDown(int rt,int m) {
if (add[rt]) {
add[rt<<1] += add[rt];
add[rt<<1|1] += add[rt];
sum[rt<<1] += add[rt] * (m - (m >> 1));
sum[rt<<1|1] += add[rt] * (m >> 1);
add[rt] = 0;
}
}
void build(int l,int r,int rt) {
add[rt] = 0;
if (l == r) {
scanf("%lld",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt) {
if (L <= l && r <= R) {
add[rt] += c;
sum[rt] += (LL)c * (r - l + 1);
return ;
}
PushDown(rt , r - l + 1);
int m = (l + r) >> 1;
if (L <= m) update(L , R , c , lson);
if (m < R) update(L , R , c , rson);
PushUp(rt);
}