//
// Created by zhengwei.
//
#include <iostream>
using namespace std;
const int MaxN = 5e4 + 1;
int N = 6;
int data[] = {-1, 2, 3, 1, 5, 8, 7};//原始数据,第一个数字作废
/*===线段树,求区间最值===*/
class SegTree {
public:
int l, r;//区间边界
int maxx;//区间最值
SegTree *tl, *tr;//左右子树
SegTree(int _from, int _to) : maxx(0) {
this->l = _from;
this->r = _to;
}
};
/**
* @param pid 数组下标,一般从1开始
* @param l 区间起点
* @param r 区间终点
*/
SegTree *build(int l, int r) {
SegTree *root = new SegTree(l, r);
if (l == r) {
root->maxx = data[l];//这里体现原始数组的作用
return root;
}
int mid = l + ((r - l) >> 1);
root->tl = build(l, mid);//左子
root->tr = build(mid + 1, r);//右子
root->maxx = max(root->tl->maxx, root->tr->maxx);//回溯更新最值
return root;
}
/**
* 单点更新
* @param root
* @param x 要更新的下标
* @param value 新的值
*/
void update(SegTree *root, int x, int value) {
int l = root->l;
int r = root->r;
if (l == r && l == x) {
root->maxx = value;//这个区间就是[x,x],叶子节点
return;
}
int mid = l + ((r - l) >> 1);
SegTree *lson = root->tl;
SegTree *rson = root->tr;
if(x<=mid) {
update(lson,x,value);
}else {
update(rson,x,value);
}
// 回溯更新最值
root->maxx=max(lson->maxx,rson->maxx);
}
int query_ans = 0;
/**
*
* @param l 左边界
* @param r 右边界
* @param from 区间开始
* @param to 区间结束
* @return
*/
void query(SegTree *root, int ql, int qr) {
int l = root->l;
int r = root->r;
if (ql <= l && qr >= r) {//查询区间在当前节点所代表的区间范围内,可直接返回结果
query_ans = max(query_ans, root->maxx);
return;
}
int mid = l + ((r - l) >> 1);
if (ql <= mid)query(root->tl, ql, qr);
if (qr > mid)query(root->tr, ql, qr);
}
/*===线段树,求区间最值 end===*/
//int data[] = {-1, 2, 3, 1, 5, 8, 7};//原始数据,第一个数字作废
int main(int argc, const char * argv[]) {
SegTree *pSegTree = build(1, N);
query(pSegTree, 2, 4);
printf("%d\n", query_ans);
query_ans=0;
update(pSegTree,1,9);
query(pSegTree, 1, 5);
printf("%d\n", query_ans);
return 0;
}
mark线段树模板(以维护最值为例)
猜你喜欢
转载自blog.csdn.net/zhengwei223/article/details/87570713
今日推荐
周排行