C++编程题之查分数

 

 1 #include<bits/stdc++.h>
 2 #define N 200009
 3 using namespace std;
 4 typedef long long ll;
 5 ll n,m,a[N],b[N],bm[N],L;//a代表学生的初始成绩 
 6 ll update(ll x,ll y){
 7     if(y<a[x]&&a[x]==bm[b[x]]){//如果块内老擂主变小,块内重新比较 
 8         a[x]=y;
 9         ll r=b[x]*L;
10         ll l=r-L+1;
11         bm[b[x]]=*max_element(a+l,a+r+1);
12     }
13     else{//否则直接和老擂主单挑 
14         a[x]=y;
15         bm[b[x]]=max(bm[b[x]],y);
16     }
17 }
18 int rmq(int l,int r){
19     int s=0;
20     if(b[l]==b[r]){//两个点在同一个block 
21         for(int i=l;i<=r;i++)
22             if(a[i]>s)s=a[i];
23     }else{//两个点不在同一个block 
24         for(int i=l;b[i]==b[l];i++)//计算第一个点所在的block的最大值 
25             if(a[i]>s)s=a[i];
26         for(int i=r;b[i]==b[r];i--)//计算第二个点所在的block的最大值 
27             if(a[i]>s)s=a[i];
28         for(int k=b[l]+1;k<=b[r]-1;k++)//计算中间部分的最大值 
29             if(bm[k]>s)s=bm[k];
30     }
31     return s;
32 }
33 int main(){
34     cin>>n>>m;
35     for(int i=1;i<=n;i++)cin>>a[i];
36     L=sqrt(n);//计算块数 
37     for(int i=1;i<=n;i++)b[i]=(i-1)/L+1;//分块 
38     for(int k=1;k<=b[n];k++){//计算每个block的最大值 
39         ll r=k*L;
40         ll l=r-L+1;
41         bm[k]=*max_element(a+l,a+r+1);
42     }
43     for(int i=1;i<=m;i++){
44         char C;//Q:查询操作;U:更新操作。 
45         int x,y;
46         cin>>C>>x>>y;
47         if(C=='U')update(x,y);//更新操作:将x号学生的成绩改为y 
48         else cout<<rmq(x,y)<<' ';//查询操作:x~y号学生中最高是多少 
49     }
50     cout<<endl;
51     return 0;
52 }

 

学校里共n位学生,编号1n。作为校长,你有若干个询问从某某学号到某某学号当中,目前分数最高的是多少。在询问期间,老师们可能会发现学生成绩登记错误,就会出现若干次修改。

输入第一行包含两个正整数nm (均不超过200000),代表学生的数目和操作的数目。

第二行包含n个正整数,代表这n个学生的初始成绩,均不超过109

接下来有m: 开头有一个字符(只取QU) ,和两个正整数AB

CQ时表示一条询问操作:学号AB(包括A,B)中成绩最高的是多少,1<=A<=B<=N

CU时表示一条更新操作,A学生的成绩改成B1<=A<=N分数B不超过109

输出一行:对于每一次询问操作,在一行里面输出最高成绩,由空格隔开。 

输入样例

5 3

1 2 3 4 5

Q 1 5

U 5 1

Q 1 5

输出样例

5 4

 

 

猜你喜欢

转载自www.cnblogs.com/ACTVnews-InYourFace/p/12458271.html