I hate it(最小単点修正区間クエリー)
9042 ワード
転送ゲートHDU-1754
説明
多くの学校では比較的な習慣が流行している.先生たちは聞くのが好きで、○○から○○までの中で、点数が一番高いのはいくらですか.これは多くの学生に反感を抱かせた.あなたが喜ぶかどうかにかかわらず、今あなたがしなければならないのは、先生の要求に従って、プログラムを書いて、先生の質問をシミュレートすることです.もちろん、先生はある同級生の成績を更新する必要があることがあります.
入力
この問題には複数のテストが含まれています.ファイルが終わるまで処理してください.各試験の1行目には、2つの正の整数NとM(0学生ID番号はそれぞれ1からNに編成される.2行目にはN個の整数が含まれ、このN個の学生の初期成績を表し、i番目の数はIDがiの学生の成績を表す.次はM行である.各行には1文字C(‘Q’または’U’のみを取る)と2つの正の整数A,Bがある.Cが‘Q’である場合、これはAからB(A,Bを含む)までのIDの学生の中で、成績が最も高いものはどれくらいかを尋ねる質問操作であることを示す.Cが‘U’である場合、IDがAの学生の成績をBに変更するように要求する更新操作であることを示す.
しゅつりょく
問合せ操作ごとに、1行に最高成績を出力します.
サンプル
構想
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using namespace std;
struct Tree{
int num,l,r;
}tree[1000007];
void build(int l,int r,int d){
tree[d]=(Tree){-1000,l,r};
if(l==r)return ;
int mid=(tree[d].l+tree[d].r)/2;
build(l,mid,d<<1);
build(mid+1,r,d<<1|1);
}
void update(int a,int b,int d){
if(tree[d].l==tree[d].r){
tree[d].num=b;
return;
}
int mid=(tree[d].l+tree[d].r)/2;
if(a<=mid) update(a,b,d<<1);
else update(a,b,d<<1|1);
tree[d].num=max(tree[d<<1].num,tree[d<<1|1].num);
}
int find(int l,int r,int d){
if(tree[d].l==l&&tree[d].r==r)
return tree[d].num;
int mid=(tree[d].l+tree[d].r)/2;
if(r<=mid) return find(l,r,d<<1);
else if(l>mid) return find(l,r,d<<1|1);
else return max(find(l,mid,d<<1),find(mid+1,r,d<<1|1));
}
int main(){
int n,m,tem;
while(~scanf("%d %d",&n,&m)){
build(1,n,1);
for(int i=1;i<=n;i++){
scanf("%d",&tem);
update(i,tem,1);
}
char s[5];
int x,y;
while(m--){
scanf("%s",s);
scanf("%d %d",&x,&y);
if(s[0]=='Q')
printf("%lld
",find(x,y,1));
else
update(x,y,1);
}
}
return 0;
}