B-I Hate It(非再帰版)


多くの学校では比較的な習慣が流行している.先生たちは聞くのが好きで、○○から○○までの中で、点数が一番高いのはいくらですか.これは多くの学生に反感を抱かせた.あなたが喜ぶかどうかにかかわらず、今あなたがしなければならないのは、先生の要求に従って、プログラムを書いて、先生の質問をシミュレートすることです.もちろん、先生はある同級生の成績を更新する必要があることがあります.
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」の場合、これは
#include

using namespace std;

const int MAXN = 200000 + 10;
int sum[MAXN << 2], a[MAXN], N, n, m;

void build()
{
	while(N < n + 2)
		N <<= 1;
	for(int i = 1; i <= n ; i ++)
		sum[N + i] = a[i];
	for(int i = N - 1; i > 0; i --)
		sum[i] = max (sum[i << 1], sum[i << 1 | 1]);
}

int query(int L, int R)
{
	int s, t, x = 1;
	int ans = 0;
	for(s = N + L - 1, t = N + R + 1; s ^ t ^ 1; s >>= 1, t >>= 1)
	{

		if(~s & 1)
			ans = max (ans, sum[s ^ 1]);
		if(t & 1)
			ans = max (ans, sum[t ^ 1]);
	}
	return ans;
}
void update(int x, int k)
{
	sum[x + N] = k;
	for(int s = (x + N) >> 1; s; s >>= 1)
		sum[s] = max (sum[s << 1], sum[s << 1 | 1]);
}
int main()
{
	int T, x, y, cas = 0;
	char q[10];
	while(~scanf("%d %d", &n, &m))
	{
		cas ++;
		memset(sum, 0, sizeof(sum));
		memset(a, 0, sizeof(a));
		N = 1;
		for(int i = 1; i <= n; i ++)
			scanf("%d", &a[i]);
		build();
		while(m --)
		{
			scanf("%s %d %d", q, &x, &y);
			if(q[0] == 'Q')
				printf("%d
", query(x, y)); else if(q[0] == 'U') update(x, y); } } return 0; }

AからB(A,Bを含む)までのIDの学生の中で、成績が最も高いのはいくらですか.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