HDU - 1754 I Hate It (线段树)

解析:线段树模板题,线段树单点更新,找出区间最大值和更改区间点的值。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200000;
int a[N];
int s[N << 2], L[N << 2], R[N << 2];
void build(int u,int l,int r) {
	if(l == r) {
		L[u] = R[u] = l;
		s[u] = a[l];
		return ;
	}
	int mid = (l + r) / 2;
	build(u*2,l,mid);
	build(u*2+1,mid+1,r);
	L[u] = l;
	R[u] = r;
	s[u] = max(s[u*2],s[u*2+1]);
}
void modify(int u,int x,int v) {
	if(R[u] == x && L[u] == x) {//叶子节点,找到结果返回
		s[u] = v;
		return ;
	}
	int mid = (L[u] + R[u]) / 2;
	if(x <= mid) {
		modify(u*2,x,v);
	}else {
		modify(u*2+1,x,v);
	}
	s[u] = max(s[u*2],s[u*2+1]);
}
int query(int u,int l,int r) {
	if(l <= L[u] && R[u] <= r) {
		return s[u];
	}
	int mid = (L[u] + R[u]) / 2;
	int ret = -N;
	if(l <= mid) {
		ret = max(ret,query(u*2,l,r));
	}
	if(r > mid) {
		ret = max(ret,query(u*2+1,l,r));
	}
	return ret;
}
int main() {
	int m,n;
	int x,y;
	while(scanf("%d%d",&n,&m) != EOF) {
		for(int i = 1; i <= n; i++) {
			scanf("%d",&a[i]);
		}
		memset(s,0,sizeof(s));
		L[1] = 1;
		R[1] = n;
		build(1,L[1],R[1]);
		char cmd[3];
		while(m--) {
			scanf("%s",cmd);
			if(cmd[0] == 'Q') {
				scanf("%d%d",&x,&y);
				printf("%d\n",query(1,x,y));
			}else if(cmd[0] == 'U') {
				scanf("%d%d",&x,&y);
				modify(1,x,y);
			}
		}
	}
	return 0;
}


你可能感兴趣的:(it,HDU,1754,I,hate)