1. 程式人生 > 其它 >I Hate It

I Hate It

原題連結:http://acm.hdu.edu.cn/showproblem.php?pid=1754

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:

對於每一次詢問操作,在一行裡面輸出最高成績。

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

解題思路:

線段樹模板題,本題包含建樹、向上回溯、單點修改、區間查詢

AC程式碼:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 200005;
int g[maxn];									//定義成績陣列
int arr[maxn * 4];								//定義樹的資料陣列
void pushup(int node)
{
	arr[node] = max(arr[node * 2], arr[node * 2 + 1]);			//向上回溯
}
void build(int l, int r, int node)
{
	if (l == r)
	{
		arr[node] = g[l];
		return;								//判斷是葉子,賦值並退出函式
	}
	int mid = (l + r) / 2;							//取中值
	build(l, mid, node * 2);						//遞迴左子樹
	build(mid + 1, r, node * 2 + 1);					//遞迴右子樹
	pushup(node);								//回溯父代		

}
int query(int a, int b, int l, int r, int node)
{
	if (a <= l && b >= r)
		return arr[node];
	int maxm = 0;
	int mid = (l + r) / 2;
	if (a <= mid)
		maxm = max(maxm, query(a, b, l, mid, node * 2));
	if (b > mid)
		maxm = max(maxm, query(a, b, mid + 1, r, node * 2 + 1));
	return maxm;
}
void update(int a, int b, int l, int r, int node)				//更新操作
{
	if (l == r)
	{
		arr[node] = b;
		return;
	}								        //判斷是葉子,把b賦給葉子
	int mid = (l + r) / 2;
	if (a <= mid)
		update(a, b, l, mid, node * 2);
	else
		update(a, b, mid + 1, r, node * 2 + 1);
	pushup(node);
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int N, M;								//N為學生數,M為操作次數
	while (cin>>N>>M)						        //輸入N,M
	{
		for (int i = 1; i <= N; i++)
		{
			cin>>g[i];						//輸入成績,從index為1開始
		}
		build(1, N, 1);							//建樹						
		char ch;							//定義操作符
		int a, b;							//定義運算元
		while (M--)
		{
			cin >> ch >> a >> b;
			if (ch == 'Q')
				cout<<query(a, b, 1, N, 1)<<endl;
			else
				update(a, b, 1, N, 1);
		}
	}
	return 0;
}