给出一个有n个元素的数组,设计一个数据结构,支持以下两种操作。
- Update(x,v):把
修改为v。
- Query(L,R):计算
// 线段树
#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;
}