题解:单点修改线段树模板题。

#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;
}