/* 标准的线段树模板 */ #include <iostream> using namespace std; const int nMax = 200010; struct Node { int l, r; int max; Node(){} Node(int l, int r, int max):l(l), r(r), max(max){} }node[nMax * 4]; int A[nMax]; int N, M; int fmax(int a, int b) { return a > b ? a : b ; } void build(int rt, int l, int r)//创建 { if(l < r) { int mid = (l + r) / 2; build(rt * 2,l, mid); build(rt * 2 + 1, mid + 1, r); int max = fmax(node[rt * 2].max, node[rt * 2 + 1].max); node[rt] = Node(l, r, max); } else if(l == r) node[rt] = Node(l, r, A[l]); } void search(int rt, int l, int r, int &max)//查询 { if(node[rt].l == l && node[rt].r == r) { max = node[rt].max; return ; } else { int mid = (node[rt].l + node[rt].r) / 2; if(mid >= r) search(rt * 2, l, r, max); else if(mid + 1 <= l) search(rt * 2 + 1, l, r, max); else { int max1, max2; search(rt * 2, l, mid, max1); search(rt * 2 + 1, mid + 1, r, max2); max = fmax(max1, max2); } } } void update(int rt, int a, int b)//更新 { if(node[rt].l == node[rt].r) { node[rt].max = b; } else { int mid = (node[rt].l + node[rt].r) / 2; if(a <= mid) update(rt * 2, a, b); else if(a >= mid + 1) update(rt * 2 + 1, a, b); node[rt].max = fmax(node[rt * 2].max, node[rt * 2 + 1].max); } } int main() { //freopen("e://data.in", "r", stdin); while(scanf("%d%d", &N, &M) != EOF) { int i; for(i = 1; i <= N; ++ i) scanf("%d", &A[i]); build(1, 1, N); char opr[10]; int a, b; for(i = 1; i <= M; ++ i) { scanf("%s%d%d", opr, &a, &b); if(opr[0] == 'Q') { int max; search(1, a, b, max); printf("%d\n", max); } else if(opr[0] == 'U') { update(1, a, b); } } } return 0; }