HDU 1754 I Hate It (線段樹 區間修改 區間最值)
阿新 • • 發佈:2018-12-18
I Hate It
Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 105843 Accepted Submission(s): 39732
Problem 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:
Hint: Huge input,the C function scanf() will work better than cin
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define rt root<<1
#define rtt root<< 1|1
#define MAXN 200005
struct tree {
int maxn;//儲存最值
int l,r;
} t[MAXN<<2];
void pushup(int root) {//向下更新
t[root].maxn=max(t[rt].maxn,t[rtt].maxn);
}
void build(int root,int l,int r) {//建樹
t[root].l=l;
t[root].r=r;
if(l==r) {
scanf("%d",&t[root].maxn);
return ;
}
int mid=(l+r)>>1;
build(root<<1,l,mid);
build(root<<1|1,mid+1,r);
pushup(root);
}
void updata(int root,int L,int R,int v) {//更新
if(L<=t[root].l&&R>=t[root].r) {
t[root].maxn=v;
return ;
}
int mid=(t[root].l+t[root].r)>>1;
if(L<=mid) {
updata(root<<1,L,R,v);
}
if(R>mid) {
updata(root<<1|1,L,R,v);
}
pushup(root);
}
int Query_maxn(int L,int R,int root){//查詢
if(L<=t[root].l&&R>=t[root].r){
return t[root].maxn;
}
int maxx=0;
int mid=(t[root].l+t[root].r)>>1;
if(L<=mid){
maxx=max(maxx,Query_maxn(L, R,root<<1));
}
if(R>mid){
maxx=max(maxx,Query_maxn(L, R,root<<1|1));
}
return maxx;
}
int main(){
int n;
int m;
while(scanf("%d%d",&n,&m)!=EOF){
build(1,1,n);
while(m--){
char a[10];
int l,r;
scanf("%s%d%d",a,&l,&r);
if(a[0]=='U'){
updata(1,l,l,r);
}
else{
printf("%d\n",Query_maxn(l,r,1));
}
}
}
return 0;
}