描述
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。 这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
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
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
6
5
9
Hint
Huge input,the C function scanf() will work better than cin
Huge input,the C function scanf() will work better than cin
题意
如上
题解
线段树区间查询,单点更新
代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 5 using namespace std; 6 7 const int N=2e5+5; 8 int a[N<<2]; 9 void PushUp(int rt) 10 { 11 a[rt]=max(a[rt<<1],a[rt<<1|1]); 12 } 13 void Build(int l,int r,int rt) 14 { 15 if(l==r) 16 { 17 scanf("%d",&a[rt]); 18 return; 19 } 20 int mid=(l+r)>>1; 21 Build(l,mid,rt<<1); 22 Build(mid+1,r,rt<<1|1); 23 PushUp(rt); 24 } 25 void Update(int L,int C,int l,int r,int rt) 26 { 27 if(l==r) 28 { 29 a[rt]=C; 30 return; 31 } 32 int mid=(l+r)>>1; 33 if(L<=mid)Update(L,C,l,mid,rt<<1); 34 else Update(L,C,mid+1,r,rt<<1|1); 35 PushUp(rt); 36 } 37 int Query(int L,int R,int l,int r,int rt) 38 { 39 if(L<=l&&r<=R) 40 return a[rt]; 41 int mid=(l+r)>>1; 42 int ans=0; 43 if(L<=mid)ans=max(ans,Query(L,R,l,mid,rt<<1)); 44 if(R>mid)ans=max(ans,Query(L,R,mid+1,r,rt<<1|1)); 45 return ans; 46 } 47 int main() 48 { 49 int n,m,x,y,t,o=1; 50 char op[15]; 51 while(scanf("%d%d",&n,&m)!=EOF) 52 { 53 Build(1,n,1); 54 for(int i=1;i<=m;i++) 55 { 56 scanf("%s%d%d",op,&x,&y); 57 if(op[0]=='Q')///x--y 58 printf("%d ",Query(x,y,1,n,1)); 59 if(op[0]=='U')///+ 60 Update(x,y,1,n,1); 61 } 62 } 63 return 0; 64 }