P1531 I Hate It题解
题目背景
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。这让很多学生很反感。
题目描述
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
输入格式
第一行,有两个正整数 n 和 m(0<n≤2×105,0<m≤2×105),分别代表学生的数目和操作的数目。学生 ID 编号分别从 1 编到 n。
第二行包含 n 个整数,代表这 n 个学生的初始成绩,其中第 i 个数代表 ID 为 i 的学生的成绩,保证学生的成绩为 1∼109 之间的正整数。
接下来有 m 行。每一行有一个字符 c(只取 Q 或 U),和两个正整数 a,b。
- 当 c 为
Q的时候,表示这是一条询问操作,它询问 ID 从 a 到 b(包括 a,b) 的学生当中,成绩最高的是多少; - 当 c 为
U的时候,表示这是一条更新操作,如果当前 a 学生的成绩低于 b,则把 ID 为 a 的学生的成绩更改为 b,否则不改动。
输出格式
对于每一次询问操作输出一行一个整数,表示最高成绩。
输入输出样例
输入 #1复制
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
输出 #1复制
5 6 5 9
思路
线段树模板题,直接做即可。
代码见下
#include <bits/stdc++.h>
using namespace std;
int n,m,a[1000006],siz[4000006],ll,rr;
long long te[4000006],lz[4000006],xx;
char ch;
void bu(int a1,int l,int r){
siz[a1]=r-l+1;
if(l==r){
te[a1]=a[l];
return ;
}
int mid=(l+r)/2;
bu(a1*2,l,mid);
bu(a1*2+1,mid+1,r);
te[a1]=max(te[a1*2],te[a1*2+1]);
return ;
}//l~r建树节点a1
void ci(int a1,int l,int r,int x,long long v){
if(l==r&&l==x){
te[a1]=max(te[a1],v);
return ;
}
int mid=(l+r)/2;
if(x<=mid){
ci(a1*2,l,mid,x,v);
}
if(mid+1<=x){
ci(a1*2+1,mid+1,r,x,v);
}
te[a1]=max(te[a1*2],te[a1*2+1]);
return ;
}//x~y区间加v至l~r区间a1点
long long co(int a1,int l,int r,int x,int y){
if(x<=l&&r<=y){
return te[a1];
}
int mid=(l+r)/2;
long long dbdb=0;
if(mid>=x){
dbdb=max(dbdb,co(a1*2,l,mid,x,y));
}
if(mid+1<=y){
dbdb=max(dbdb,co(a1*2+1,mid+1,r,x,y));
}
return dbdb;
}//x~y区间问至l~r区间a1点
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
bu(1,1,n);
for(int i=1;i<=m;i++){
cin>>ch;
if(ch=='U'){
cin>>ll>>xx;
ci(1,1,n,ll,xx);
}
else{
cin>>ll>>rr;
cout<<co(1,1,n,ll,rr)<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号