修改#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxx = 200005; int k[maxx], k2[maxx*4]; void compare(int x) { k2[x] = max(k2[x * 2], k2[x * 2 + 1]); } void tree(int l, int r, int x) { if (l == r) { k2[x] = k[l]; return; } int mid = (l + r) / 2; tree(l, mid, x * 2); tree(mid + 1, r, x * 2 + 1); compare(x); } int query(int L, int R, int l, int r, int rt) { if (L <= l && R >= r) return k2[rt]; int mid = (l + r) / 2; int ret = 0; if (L <= mid) ret = max(ret, query(L, R, l, mid, rt * 2)); if (R > mid) ret = max(ret, query(L, R, mid + 1, r, rt * 2 + 1)); return ret; } void correct(int s1, int s2, int l, int r, int v) { if (l == r) { k[v] = max(s2, k[v]); return; } int mid = (l + r) / 2; if (s1 <= mid) correct(s1, s2, l, mid, v * 2); else correct(s1, s2, mid+1, r, v * 2+1); compare(v); } int main() { int n, m; while (scanf("%d%d", &n, &m) != EOF) { for (int i = 1; i <= n; i++) scanf("%d", &k[i]); tree(1, n, 1); while (m--) { char a; int b, c; scanf(" %c%d%d", &a, &b, &c); if (a == 'Q') printf("%d\n", query(b, c, 1, n, 1)); else correct(b, c, 1, n, 1); } } return 0; }
时间: 2024-04-17 17:28:17 浏览: 132
使用include <iostream>时一定要加using namespace std
这段代码是一个用线段树实现的区间最大值查询和区间最大值修改程序。它包含了以下几个:
1. `compare()` 函数用于比两个子节点的最大值,并更新父节点的最大值。
2. `tree()` 函数用于构建线段树,将数组 `k` 中的元素存储在叶子节点中,并逐层向上更新父节点的最大值。
3. `query()` 函数用于查询区间 `[L, R]` 的最大值。首先判断当前节点表示的区间是否包含在查询区间内,如果是,则直接返回当前节点存储的最大值;否则,将查询区间分为两部分,并递归查询左右子节点中的最大值,并返回较大的那个。
4. `correct()` 函数用于修改区间 `[s1, s2]` 中的元素。如果当前节点表示的区间只包含一个元素,则更新该元素为 `s2` 和当前元素的较大值;否则,根据 `s1` 的位置将修改操作分配给左右子节点,并递归更新。
在 `main()` 函数中,首先读入数组 `k` 的大小和查询次数。然后循环读入数组 `k` 的元素,并调用 `tree()` 函数构建线段树。接下来,根据输入的操作类型进行查询或修改操作,并输出相应的结果。
如果你有任何问题,可以继续问我。
阅读全文