/*B - I Hate It
Time Limit:3000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit
Status
Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要
更新某位同学的成绩。
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
Q 1 5
Sample Output
5
6
5
9
Hint
Huge input,the C function scanf() will work better than cin
*/
#include <cstdio>
#include <algorithm>
#include <ctime>
using namespace std;
int N,M;
const int SIZE = 200010,INTMIN = -2147483647;
int g_students[SIZE],g_segTree[SIZE*4];//定义四倍空间节点
//node对应区间[begin,end]。node是g_segTree,begin~end是g_students
void Build(int node,int begin,int end){
if(begin==end){
g_segTree[node] = g_students[begin];
return ;
}
int mid = (begin + end) >> 1;
Build(2*node,begin,mid);
Build(2*node+1,mid+1,end);
g_segTree[node] = max(g_segTree[2*node],g_segTree[2*node+1]);
return ;
}
int Query(int node,int begin,int end,int q_left,int q_right){
if(q_left>end || q_right<begin) return INTMIN ;
if(q_left<=begin && end <= q_right) return g_segTree[node];
int mid = begin + ((end-begin)>>1);
int lson = Query(node*2,begin,mid,q_left,q_right);
int rson = Query(node*2+1,mid+1,end,q_left,q_right);
return max(lson,rson);
}
/*
进行节点的更新,同时注意对树的维护,因为一个节点的改变会涉及到一部分
当C为'U'的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。
要时刻明确node是线段树上的节点,即g_segTree的元素,其对应的是g_students上的区间[begin,end],而题目中输
入的更新学生ID对应的是g_students中的元素下标
*/
void Update(int node,int begin,int end,int indexer,int data){
if(begin==end && indexer==begin){//单节点更新,
g_segTree[node] = data;
return ;
}
//找到待更新的子树
int mid = (begin+end) >> 1;//区间分割
if(indexer <= mid) Update(2*node,begin,mid,indexer,data);
else Update(2*node+1,mid+1,end,indexer,data);
g_segTree[node] = max(g_segTree[2*node],g_segTree[2*node+1]);
return ;
}
int main(){
while(scanf("%d %d",&N,&M)!=EOF){
getchar();
for(int i=1;i<=N;i++) scanf("%d",g_students+i);
Build(1,1,N);
char C;
int A,B;
while(M--){
getchar();
scanf("%c %d %d",&C,&A,&B);
if(C=='Q'){
//查询区间为[A,B],A应该<=B
if(A>B) swap(A,B);//但这一句只能写到if内,,不能写在上面,因为对于Update操作,
int res = Query(1,1,N,A,B);//A是节点,B是待更新的成绩,A,B大小关系不确定是理所应当的
printf("%d\n", res);
}//注意
else if(C=='U') Update(1,1,N,A,B);
}
}
return 0;
}
HDU 1754 I hate it
最新推荐文章于 2020-09-30 13:33:24 发布
本文介绍了一个程序,用于处理学生分数的相关操作,包括查询指定范围内最高分数和更新学生分数。程序采用线段树结构来高效地执行这些操作。
2549

被折叠的 条评论
为什么被折叠?



