【基础线段树】toj2762Balanced Lineup

题意:给N只金宝的长度,Q次查询,给出区间[A, B]上最大值和最小值之差。

线段树入门.

线段树比较灵活,写法都是随心而为,不必拘泥于实现,抓住其更本质的数据结构思想即可。

//segment tree
//all bounds are tight. for bound (A, B), it means [A, B]

#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;

const int MAX = 50007;
int height[MAX];
struct node {
	//int left, right;
	int min, max;
} a[MAX << 2];
int N, Q;

inline int L(const int& x) {
	return x << 1;
}

inline int R(const int& x) {
	return x << 1 | 1;
}

void build(int root, int left, int right) {
	//printf("build (%d, %d, %d)\n", root, left, right);
	//getchar();
	if (left > right) return;
	//a[root].left = left, a[root].right = right;
	if (left == right) {
		a[root].min = a[root].max = height[left];
	} else {
		int mid = (left + right) >> 1;
		build(L(root), left, mid);
		build(R(root), mid + 1, right);
		a[root].min = min(a[L(root)].min, a[R(root)].min);
		a[root].max = max(a[L(root)].max, a[R(root)].max);
	}
}

//flag = true: max
//flag = false: min
int query(int root, int left, int right, int s, int e, bool flag) {
	if (left >= s && right <= e) {
		return flag ? a[root].max : a[root].min;
	} else if (left > e || right < s) {
		return flag ? 0 : 0x7fffffff;
	} else {
		int mid = (left + right) >> 1;
		int a = query(L(root), left, mid, s, e, flag);
		int b = query(R(root), mid + 1, right, s, e, flag);
		return flag ? max(a, b) : min(a, b);
	}
}

int main() {
	while (~scanf(" %d %d", &N, &Q)) {
		for (int i = 1; i <= N; ++i) {
			scanf(" %d", height + i);
		}
		build(1, 1, N);
		int A, B;
		while (Q--) {
			scanf(" %d %d", &A, &B);
			printf("%d\n", query(1, 1, N, A, B, true) - query(1, 1, N, A, B, false));
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值