题目大意:

给定一个序列和两种操作:

Q操作,表示这是一条询问操作,询问区间[a,b]当中的元素的最大值是多少。

U操作,表示这是一条更新操作,要求把元素A的值更改为B。

思路:

线段树模板题。

代码:

#include<iostream>
#include<stdio.h>
using namespace std;
#define MAXSIZE 200000
int val[MAXSIZE+1];
struct node
{
	int max;
	int left;
	int right;
}tree[MAXSIZE*3];
int max(int x,int y)
{
	return x>y?x:y;
}
int create(int root,int left,int right)
//以root为根节点建树。 
{
	tree[root].left=left;
	tree[root].right=right;
	if(left==right)
		return tree[root].max=val[left];
	int a,b,middle=(left+right)/2;
	a=create(2*root,left,middle);
	b=create(2*root+1,middle+1,right);
	return tree[root].max=max(a,b);
}
int calculate(int root,int left,int right)
//以root为根节点的线段树中,求取区间[left,right]中的最大值。 
{
	if(tree[root].left>right||tree[root].right<left)
		return 0;
	if(left<=tree[root].left&&tree[root].right<=right)
		return tree[root].max;
	int a,b;
	a=calculate(2*root,left,right);
	b=calculate(2*root+1,left,right);
	return max(a,b);
}
int updata(int root,int pos,int val)
//以root为根节点的线段树中,将位置pos的元素更新为val。 
{
	if(pos<tree[root].left||tree[root].right<pos)
		return tree[root].max;
	if(tree[root].left==pos&&tree[root].right==pos)
		return tree[root].max=val;
	int a,b;
	a=updata(2*root,pos,val);
	b=updata(2*root+1,pos,val);
	return tree[root].max=max(a,b);
}
int main()
{
	int n,m;
	while(~scanf("%d%d",&n,&m))
	{
		for(int i=1;i<=n;i++)
			scanf("%d",&val[i]);
		create(1,1,n);
		for(int i=0;i<m;i++)
		{
			char op;
			int a,b;
			scanf("\n%c%d%d",&op,&a,&b);
			if(op=='Q')
				printf("%d\n",calculate(1,a,b));
			else
				updata(1,a,b);
		}
	}
}