I Hate It
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 93269 Accepted Submission(s): 35359
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。
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
Hint
Huge input,the C function scanf() will work better than cin
1 PS:通过ios::sync_with_stdio(false);可以加快数据cin、cout的输入输出
分析:
1 如果直接在每一步进行遍历求最大值,时间复杂度为O(n*m),所以考虑数据结构中的线段树
算法模板 (线段树)(1、build_tree(int i, int l, int r);2、update_tree(int r);3、query_tree(int i, int l, intr)):
1 void build_tree(int i, int l, int r) 2 { 3 node[i].l = l; 4 node[i].r = r; 5 node[i].value = 0; 6 if (l == r) 7 { 8 pre[l] = i; 9 return ; 10 } 11 build_tree (i <<1, l, (int)(floor(l+r)/2.0)); 12 build_tree ((i <<1) + 1, (int)(floor(l+r)/2.0)+1, r); 13 } 14 15 void update_tree(int r) 16 { 17 if (r == 1) return ; 18 int f = r / 2; 19 int a = node[f>>1].value; 20 int b = node[(f>>1)+1].value; 21 node[f].value = max(a, b); 22 update_tree(f); 23 } 24 25 void query_tree(int i, int l, int r) 26 { 27 if (node[i].l == l && ndoe[i].r == r) 28 { 29 ans = max(ans, node[i].value); 30 return ; 31 } 32 i = i<<1; 33 if (l <= node[i].r) 34 { 35 if (r <= node[i].r) query_tree(i, l, r); 36 else query_tree(i, l, node[i].r); 37 } 38 ++ i; 39 if (r >= node[i].l) 40 { 41 if (l >= node[i].l) query_tree(i, l, r); 42 else query_tree(i, node[i].l, r); 43 } 44 }
C/C++代码实现(AC):
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int MAXNODE = 1<<19; 6 const int MAXN = 2e6 + 10; 7 int pre[MAXN], n, m, temp, ans; 8 9 struct node 10 { 11 int l, r, value; 12 }P[MAXNODE]; 13 14 void build_tree(int i, int l, int r) 15 { 16 P[i].l = l; 17 P[i].r = r; 18 P[i].value = 0; 19 if (l == r) 20 { 21 pre[l] = i; 22 return ; 23 } 24 build_tree(i<<1, l, (int)(floor(l + r) / 2.0)); 25 build_tree((i<<1) + 1, (int)(floor(l + r) / 2.0) + 1, r); 26 } 27 28 void update_tree(int r) 29 { 30 if (r == 1) return ; 31 int f = r / 2; 32 int a = P[f<<1].value; 33 int b = P[(f<<1)+1].value; 34 P[f].value = max(a, b); 35 update_tree(f); 36 } 37 38 void query_tree(int i, int l, int r) 39 { 40 if (P[i].l == l && P[i].r == r) 41 { 42 ans = max(ans, P[i].value); 43 return ; 44 } 45 i = i <<1; 46 if (l <= P[i].r) 47 { 48 if (r <= P[i].r) query_tree(i, l, r); 49 else query_tree(i, l, P[i].r); 50 } 51 i ++; 52 if (r >= P[i].l) 53 { 54 if (l >= P[i].l) query_tree(i, l, r); 55 else query_tree(i, P[i].l, r); 56 } 57 } 58 59 int main() 60 { 61 ios::sync_with_stdio(false); 62 while(cin >>n >>m) 63 { 64 build_tree(1, 1, n); 65 for(int i = 1; i <= n; ++i) 66 { 67 cin >>temp; 68 P[pre[i]].value = temp; 69 update_tree(pre[i]); 70 } 71 int a, b; 72 char op; 73 while(m --) 74 { 75 ans = 0; 76 cin >>op >>a >>b; 77 if (op == 'Q') 78 { 79 query_tree(1, a, b); 80 cout <<ans <<endl; 81 } 82 else 83 { 84 P[pre[a]].value = b; 85 update_tree(pre[a]); 86 } 87 } 88 } 89 return 0; 90 }