不少学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。这让不少学生很反感。ios
无论你喜不喜欢,如今须要你作的是,就是按照老师的要求,写一个程序,模拟老师的询问。固然,老师有时候须要更新某位同窗的成绩ui
第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别表明学生的数目和操做的数目。学生ID编号分别从1编到N。第二行包含N个整数,表明这N个学生的初始成绩,其中第i个数表明ID为i的学生的成绩。接下来有M行。每一行有一个字符 C (只取'Q'或'U') ,和两个正整数A,B。当C为'Q'的时候,表示这是一条询问操做,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。当C为'U'的时候,表示这是一条更新操做,若是当前A学生的成绩低于B,则把ID为A的学生的成绩更改成B,不然不改动。code
对于每一次询问操做,在一行里面输出最高成绩ci
5 6get
1 2 3 4 5string
Q 1 5it
U 3 6io
Q 3 4stream
Q 4 5map
U 2 9
Q 1 5
5
6
5
9
单点修改,区间查询。
明显的线段树。
#include <cstdio> #include <cmath> #include <iostream> #include <cstdlib> #include <vector> #include <map> #include <cstring> #include <queue> #include <stack> #include <algorithm> #define re register #define Max 400100 #define gc getchar #define lson x<<1 #define rson x<<1|1 int max(int a, int b) {return a > b ? a : b;} struct HATE { int l, r, max; }t[Max << 1]; int m, n, pts[Max >> 1]; void up(int x) {t[x].max = max(t[lson].max, t[rson].max);} void build(int l, int r, int x) { t[x].l = l; t[x].r = r; if(l == r) { t[x].max = pts[l]; return ; } int mid = l + r >> 1; build(l, mid, lson); build(mid+1, r, rson); up(x); } void data(int f, int x, int k) { if(t[x].l == f && t[x].r == f) { if(t[x].max < k) t[x].max = k; return ; } int mid = t[x].l + t[x].r >> 1; if(f <= mid) data(f,lson,k); if(f > mid) data(f,rson,k); up(x); } int Ask(int l, int r, int x) { if(t[x].l >= l && t[x].r <= r) return t[x].max; int mid = t[x].l + t[x].r >> 1; int ans = - 9999999; if(l <= mid) ans = max(ans, Ask(l,r,lson)); if(r > mid) ans = max(ans, Ask(l,r,rson)); return ans; } int main() { scanf("%d%d",&n,&m); for(re int i = 1; i <= n; ++ i) scanf("%d", &pts[i]); build(1, n, 1); int l, r; char opt; for(re int i = 1; i <= m; ++ i) { std :: cin >> opt; scanf("%d %d",&l,&r); if(opt == 'U') data(l,1,r); else printf("%d\n",Ask(l,r,1)); } return 0; }