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位学生,编号1到n。作为校长,你有若干个询问:从某某学号到某某学号当中,目前分数最高的是多少。在询问期间,老师们可能会发现学生成绩登记错误,就会出现若干次修改。
输入第一行包含两个正整数n和m (均不超过200000),代表学生的数目和操作的数目。
第二行包含n个正整数,代表这n个学生的初始成绩,均不超过109。
接下来有m行: 开头有一个字符(只取Q或U) ,和两个正整数A,B。
C为Q时表示一条询问操作:学号从A到B(包括A,B)中成绩最高的是多少,1<=A<=B<=N。
C为U时表示一条更新操作,将A号学生的成绩改成B,1<=A<=N,分数B不超过109。
输出一行:对于每一次询问操作,在一行里面输出最高成绩,由空格隔开。
输入样例
5 3
1 2 3 4 5
Q 1 5
U 5 1
Q 1 5
输出样例
5 4