Problem Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 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'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
在每个测试的第一行,有两个正整数 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'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
Output
对于每一次询问操作,在一行里面输出最高成绩。
Sample Input
5 6
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 2 9
Q 1 5
Sample Output
5
6
5
9
注:这是一道线段树的入门题,主要了解其基本的操作。
1 #include <cstdio> 2 #include <cmath> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 using namespace std; 7 const int MAXN = 200005; 8 struct data 9 { 10 int left, right, Max; 11 } tree[3*MAXN]; 12 int score[MAXN]; 13 void pushUp(int node) 14 { 15 tree[node].Max = max(tree[2*node].Max, tree[2*node+1].Max); 16 } 17 void build(int left, int right, int node) //构建线段树 18 { 19 //当前节点所表示的区间 20 tree[node].left = left; 21 tree[node].right = right; 22 //左右区间相同,则此节点为叶子,Max 应储存对应某个学生的值 23 if (left == right){ 24 tree[node].Max = score[left]; 25 return; 26 } 27 //递归建立左右子树 28 int mid = left + (right - left) / 2; 29 build(left, mid, 2*node); 30 build(mid+1, right, 2*node+1); 31 //从子树中获得最大值 32 pushUp(node); 33 } 34 int query(int left, int right, int node) //查询区间[left,right]的Max值 35 { 36 //所查区间不在范围内 37 if (tree[node].left > right || tree[node].right < left) 38 return 0; 39 //所查区间包含当前节点所管理的区间 40 if (left <= tree[node].left && tree[node].right <= right) 41 return tree[node].Max; 42 int mid = (tree[node].left + tree[node].right) / 2; 43 //所查区间与当前节点所管理的区间有部分相交 44 if (right <= mid) 45 return query(left, right, 2*node); 46 else if (left > mid) 47 return query(left, right, 2*node+1); 48 else 49 return max(query(left, right, 2*node), query(left, right, 2*node+1)); 50 } 51 void Updata(int pos, int val, int node) //更新pos点的值 52 { 53 //更新当前节点的Max值 54 tree[node].Max = max(val, tree[node].Max); 55 //pos点为叶子节点 56 if (tree[node].left == pos && tree[node].right == pos){ 57 tree[node].Max = val; 58 return; 59 } 60 if (pos <= tree[2*node].right) 61 Updata(pos, val, 2*node); 62 else 63 Updata(pos, val, 2*node+1); 64 } 65 int main() 66 { 67 int n, m; 68 while (~scanf("%d %d", &n, &m)){ 69 for (int i=1; i<=n; i++) 70 scanf("%d", &score[i]); 71 build(1, n, 1); 72 char c; 73 int a, b; 74 for (int i=1; i<=m; i++){ 75 getchar(); 76 scanf("%c %d %d", &c, &a, &b); 77 if (c == 'U') 78 Updata(a, b, 1); 79 else 80 printf("%d ", query(a, b, 1)); 81 } 82 } 83 return 0; 84 }