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;
}

posted @ 2025-10-16 20:43  bz02_2023f2  阅读(1)  评论(0)    收藏  举报  来源