类型:单点更新,线段树 / 树状数组


代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
inline int Rint() {int x; scanf("%d", &x); return x;}

#define MAXN 200002
//#define MAX(x, y) (x)>(y)? (x):(y)					用这个算MAX(ret, query(L, R, a[e].mid+1, r, e<<1|1)),会超时,就因为多query了一次?
struct node {int l, mid, r, v;}a[MAXN*4];	//v表示分数
int n, m;

void pushUp(int e) { a[e].v=max(a[e<<1].v, a[e<<1|1].v); }
void build(int l, int r, int e)
{
	a[e].l=l, a[e].r=r;
	if(l==r) a[e].v=Rint();
	else
	{
		a[e].mid=(l+r)>>1;
		build(l, a[e].mid, e<<1);
		build(a[e].mid+1, r, e<<1|1);
		pushUp(e);
	}
}
void update(int p, int b, int l, int r, int e)
{
	if(l==r) { a[e].v = b; }
	else
	{
		if(p<=a[e].mid) update(p, b, l, a[e].mid, e<<1);
		else update(p, b, a[e].mid+1, r, e<<1|1);
		pushUp(e);
	}
}
int query(int L, int R, int l, int r, int e)
{
	int ret=0;
	if(L<=l && r<=R)	ret=a[e].v;		//正常情况下总有一个等号成立
	else	//	l L R r
	{
		if(L<=a[e].mid) ret = max(ret, query(L, R, l, a[e].mid, e<<1));
		if(a[e].mid<R) ret = max(ret, query(L, R, a[e].mid+1, r, e<<1|1));
	}
	return ret;
}
int main()
{
	while(scanf("%d%d", &n, &m)!=EOF)
	{
		build(1, n, 1);
		char buf[10];
		int a, b;
		while(m--)
		{
			scanf("%s%d%d", buf, &a, &b);
			if(buf[0]=='Q') printf("%d\n", query(a, b, 1, n, 1));
			else update(a, b, 1, n, 1);
		}
	}
}