I Hate It
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 86070 Accepted Submission(s): 33036
Problem Description
很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。
不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。
Input
本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<cmath>
#include<iomanip>
using namespace std;
typedef int _____I;
const int N=1e6+10;
const int INF=0x3f3f3f3f;
#define ERX(___I,__I,_I) for(_____I ___I = __I;___I < _I; ___I++)
#define ERD(___I,__I,_I) for(_____I ___I = __I;___I <= _I; ___I++)
#define RED(___I,__I,_I) for(_____I ___I = __I;___I >= _I; ___I--)
const int maxnode =1<<19; //2的19 次方
const int maxx =2e6+10;
struct act{
int value;
int left,right;
}node[maxnode];//所有的节点
int father[maxx];
void buildtree(int i,int left,int right){
node[i].left=left;
node[i].right=right;
node[i].value= 0;
if(left==right){ father[left]=i;return ;}
buildtree(i<<1,left,(int)(floor(left+right)/2.0)); //向左进行循环
buildtree((i<<1)+1,(int)(floor(left+right)/2.0)+1,right);//向右进行循环
}
void updatetree(int ri){ //更新区间的 最大值
if(ri==1) return ;
int fi=ri/2; //临时处理该节点下的 两个儿子的 最大值 并赋值给 该点的 value
int a=node[fi<<1].value; //左儿子vaule
int b=node[(fi<<1)+1].value; // 右儿子的 value
node[fi].value=max(a,b); //将两个儿子的 value 赋值给 该节点的 最大值
updatetree(ri/2); //向上更新
}
int Max;
void query(int i,int l,int r){ //查询区间的最大值
if(node[i].left==l&&node[i].right==r){ //如果要查询的区间就是 该区间 就进行更新最大值
Max=max(Max,node[i].value); //将划分的几个区间 都进行一个 最大值的筛选
return ; //结束该层递归
}
i=i<<1; //i的2次方 该节点的 左儿子
if(l<=node[i].right){ //左区间 在 当前节点的 右区间的左边 说明右交集
if(r<=node[i].right) query(i,l,r); //继续进行 递归 并且r在right的 左边就进行 l r的递归求解
else query(i,l,node[i].right); //如果r大于该节点的右边界 下一次递归就进行 l 到 最大的右区间的位置
}
i++; //该节点的右儿子
if(r>=node[i].left){ //如果需要查询的右区间 大于该点的右区间
if(l>=node[i].left) query(i,l,r);//并且需要查询的左区间 大于该点的左区间 那么久进行 l r的查询
else query(i,node[i].left,r); //否则 就进行该区间的向下的递归
}
}
int main(){
int n,m,q;
ios::sync_with_stdio(false);
while(cin>>n>>m){
buildtree(1,1,n);//建树
ERD(i,1,n){
cin>>q;
node[father[i]].value=q;
updatetree(father[i]);
}
string op;
int a,b;
while(m--){
cin>>op>>a>>b;
if(op[0]=='Q'){
Max=0;
query(1,a,b);//查询该区间的最大值
cout<<Max<<endl;
}
else{
node[father[a]].value=b;//该点的值等于 value
updatetree(father[a]);//并进行更新 最大值 该函数的作用就是 将区间中的最大值 赋给每个区间 就是该区间的最大值
}
}
}
return 0;
}