题解:单点修改线段树模板题。
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 800000;
const int INF = 0x3f3f3f3f;
int s[N], l[N], r[N], a[N];
int n, m, l1, r1, u, x;
void build(int k, int left, int right) {
if (left == right) {
l[k] = left;
r[k] = left;
s[k] = a[left];
return;
}
int mid = (left + right) / 2;
build(k * 2, left, mid);
build(k * 2 + 1, mid + 1, right);
s[k] = s[k * 2] > s[k * 2 + 1] ? s[k * 2] : s[k * 2 + 1];
l[k] = left;
r[k] = right;
}
int query(int k, int left, int right) {
if (l1 <= l[k] && r1 >= r[k])
return s[k];
int mid = (l[k] + r[k]) / 2;
int ans = -1;
if (l1 <= mid)
ans = max(ans, query(k * 2, left, mid));
if (r1 > mid)
ans = max(ans, query(k * 2 + 1, mid + 1, right));
return ans;
}
void change(int k, int left, int right) {
if (l[k] == u && r[k] == u) {
s[k] = x;
return;
}
int mid = (l[k] + r[k]) / 2;
if (u <= mid)
change(k * 2, left, mid);
else
change(k * 2 + 1, mid + 1, right);
s[k] = s[k * 2] > s[k * 2 + 1] ? s[k * 2] : s[k * 2 + 1];
}
int main() {
while (scanf("%d%d", &n, &m) == 2) {
for (int i = 1; i <= n; i++)
scanf("%d", &a[i]);
build(1, 1, n);
char c[2];
for (int i = 1; i <= m; i++) {
scanf("%s", c);
if (c[0] == 'Q') {
scanf("%d%d", &l1, &r1);
printf("%d\n", query(1, 1, n));
}
else {
scanf("%d%d", &u, &x);
change(1, 1, n);
}
}
}
return 0;
}