HDoj 1754 I Hate It【線分樹】

3477 ワード

I Hate It
Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 53738    Accepted Submission(s): 21097
Problem Description
多くの学校では比較的な習慣が流行している.先生たちは聞くのが好きで、○○から○○までの中で、点数が一番高いのはいくらですか.
これは多くの学生に反感を抱かせた.
あなたが喜ぶかどうかにかかわらず、今あなたがしなければならないのは、先生の要求に従って、プログラムを書いて、先生の質問をシミュレートすることです.もちろん、先生はある同級生の成績を更新する必要があることがあります.
 
Input
この問題には複数のテストが含まれています.ファイルが終わるまで処理してください.
各試験の第1行には、2つの正の整数NおよびM(0学生ID番号はそれぞれ1編からNまでです.
2行目はN個の整数を含み、このN個の学生の初期成績を表し、i番目の数はIDがiの学生の成績を表す.
次はM行です.各行には1文字C('Q'または'U'のみ)と2つの正の整数A,Bがある.
Cが「Q」である場合、IDがAからB(A,Bを含む)までの学生の中で、成績が最も高いかを尋ねる質問操作であることを示す.
Cが「U」の場合、IDがAの学生の成績をBに変更する更新操作であることを示す.
 
Output
問合せ操作ごとに、1行に最高成績を出力します.
 
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 <stdio.h>
#define maxn 200002

struct Node{
	int lson, rson;
	int max;
} tree[maxn << 2];
int stu[maxn];

int MAX(int a, int b)
{
	return a > b ? a : b;
}
void build(int left, int right, int rt)
{
	tree[rt].lson = left; tree[rt].rson = right;
	if(left == right){
		tree[rt].max = stu[left]; return;
	}
	
	int mid = (left + right) >> 1;
	build(left, mid, rt << 1);
	build(mid + 1, right, rt << 1 | 1);
	
	tree[rt].max = MAX(tree[rt<<1].max, tree[rt<<1|1].max);
}
void update(int pos, int val, int rt)
{
	if(tree[rt].lson == tree[rt].rson){
		tree[rt].max = val; return;
	}
	
	int mid = (tree[rt].lson + tree[rt].rson) >> 1;
	if(pos <= mid) update(pos, val, rt << 1);
	else update(pos, val, rt << 1 | 1);
	
	tree[rt].max = MAX(tree[rt<<1].max, tree[rt<<1|1].max);
}
int query(int left, int right, int rt)
{
	if(tree[rt].lson == left && right == tree[rt].rson){
		return tree[rt].max;
	}
	
	int mid = (tree[rt].lson + tree[rt].rson) >> 1;
	if(right <= mid) return query(left, right, rt << 1);
	else if(left > mid) 
		return query(left, right, rt << 1 | 1);
	return MAX(query(left, mid, rt << 1), query(mid+1, right, rt<<1|1));
}

int main()
{
	int N, M, i, a, b;
	char ch[2];
	while(scanf("%d%d", &N, &M) == 2){
		for(i = 1; i <= N; ++i)
			scanf("%d", &stu[i]);
		build(1, N, 1);
		
		while(M--){
			scanf("%s%d%d", ch, &a, &b);
			if(ch[0] == 'U') update(a, b, 1);
			else printf("%d
", query(a, b, 1)); } } return 0; }