动态范围最小值问题

本文介绍了一种基于线段树的数据结构实现,该结构能够高效地进行区间查询和单点更新操作。通过实例演示了如何使用线段树来解决数组上的动态查询问题,包括查询区间最小值和更新特定位置的数值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出一个有n个元素的数组A_{1},A_{2},...,A_{n},设计一个数据结构,支持以下两种操作。

  • Update(x,v):把A_{x}修改为v。
  • Query(L,R):计算min \left \{ A_{L},A_{L+1},...A_{R} \right \}
// 线段树 
#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn = 10005;
const int inf = 0x3f3f3f3f;
int minv[maxn<<2];

int ql, qr; // 查询[ql,qr]中的最小值 
int query(int o, int l, int r) {
	int m = (l + r) / 2, ans = inf;
	int lc = o * 2, rc = o * 2 + 1;
	if (ql <= l && r <= qr) return minv[o]; // 当前结点完全包含在查询区间中 
	if (ql <= m) ans = min(ans, query(lc, l, m)); // 往左走 
	if (m < qr) ans = min(ans, query(rc, m + 1, r)); // 往右走 
	return ans;
}

int p, v; // 修改:a[p] = v; 
void update(int o, int l, int r) {
	int m = (l + r) / 2;
	int lc = o * 2, rc = o * 2 + 1;
	if (l == r) { // 叶结点,直接更新minv 
		minv[o] = v; 
	} else { // l < r
		// 先递归更新左子树或者右子树 
		if (p <= m) update(lc, l, m);
		else update(rc, m + 1, r);
		// 然后计算本结点的minv 
		minv[o] = min(minv[lc], minv[rc]);
	}
}

int main() {
	
	int n;
	scanf("%d", &n);
	// 建树 
	for (int i = 1; i <= n; i++) {
		scanf("%d", &v);
		p = i;
		update(1, 1, n);
	}
	 
	int op;
	while (scanf("%d", &op) == 1) {
		if (op) {
			scanf("%d%d", &ql, &qr);
			printf("%d\n", query(1, 1, n));
		} else {
			scanf("%d%d", &p, &v);
			update(1, 1, n);
		}
	}
	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值