#include <bits/stdc++.h>
using namespace std;
int a[] = {5, 3, 7, 2, 12, 1, 6, 4, 8, 15};
const int inf = INT_MAX;
struct Tree {
int l, r, mx;
}tree[500];
// 创建线段树 节点的储存下标为k 节点区间为[l, r] 以最大值为例
/*
* 1. 若是叶子节点(l == r) 则节点的最值就是对应位置的元素值
* 2. 若是非叶子节点, 则递归创建左子树和右子树
* 3. 节点的区间最值等于该节点左右子树的最大值
*/
void build(int k, int l, int r) {
tree[k].l = l;
tree[k].r = r;
if (l == r) {
tree[k].mx = a[l];
return ;
}
int mid = (l + r) / 2;
int lc = k * 2;
int rc = k * 2 + 1;
build(lc, l, mid);
build(rc, mid + 1, r);
tree[k].mx = max(tree[lc].mx, tree[rc].mx);
}
// 点更新指修改一个元素的值 a[i] 更新为 val
/*
* 1. 若是叶子节点 满足l == r && l = i 表示找到了要修改的叶子节点 则修改节点的最值为val
* 2. 若是非叶子节点,则判断是在左子树中更新还是右子树中更新
* 3. 返回时更新节点的最值
*/
void update(int k, int i, int val) {
// 找到a[i]
if (tree[k].l == tree[k].r && tree[k].l == i) {
tree[k].mx = val;
return ;
}
int mid = (tree[k].l + tree[k].r) / 2;
int lc = k * 2;
int rc = k * 2 + 1;
if (i <= mid) update(lc, i, val); // 到左子树更新
else update(rc, i, val);
// 返回时更新最值
tree[k].mx = max(tree[lc].mx, tree[rc].mx);
}
// 区间查询 指查询[l, r]区间的最值
/*
* 1. 若节点所在的区间被查询区间[L, R]覆盖则返回该区间的最值
* 2. 判断在左子树还是右子树中查询
* 3. 返回最值
//*/
int query(int k, int l, int r) {
if (tree[k].l >= l && tree[k].r <= r) {
return tree[k].mx;
}
int mid, lc, rc;
mid = (tree[k].l + tree[k].r) / 2;
lc = k * 2;
rc = k * 2 + 1;
int Max = -inf;
if (l <= mid) Max = max(Max, query(lc, l, r));
if (r > mid) Max = max(Max, query(rc, l, r));
return Max;
}
int main() {
return 0;
}
线段树基本操作
最新推荐文章于 2024-11-04 19:24:37 发布