POJ-3264 Balanced Lineup【RMQ】

题目链接:http://poj.org/problem?id=3264

题目大意:

一个农夫有N头牛,每头牛的高度不同,我们需要找出最高的牛和最低的牛的高度差。

解题思路:

我是用RMQ写的。

N为50000,Q为200000,如果我们暴力的话,需要50000*200000=10000000000,需要25s左右.所以我们需要高效的算法,而RMQ正好解决的就是区间最值问题,复杂度为nlogn,这样就可以了。

另外还可以用线段树,因为线段树的别名就是区间树。segment tree


代码如下:

#include
#include
#include
#include
#include
#include
using namespace std;

const int N = 50005;
int FMAX[N][20], FMIN[N][20];

void RMQ(int n)
{
	for(int j = 1; j != 20; ++j)
	{
		for(int i = 1; i <= n; ++i)
		{
			if(i + (1 << j) - 1 <= n)
			{
				FMAX[i][j] = max(FMAX[i][j - 1], FMAX[i + (1 << (j - 1))][j - 1]);
				FMIN[i][j] = min(FMIN[i][j - 1], FMIN[i + (1 << (j - 1))][j - 1]);
			}
		}
	}
}

int main()
{
	int num, query;
	int a, b;
	while(scanf("%d %d", &num, &query) != EOF)
	{
		for(int i = 1; i <= num; ++i)
		{
			scanf("%d", &FMAX[i][0]);
			FMIN[i][0] = FMAX[i][0];
		}
		RMQ(num);
		while(query--)
		{
			scanf("%d%d", &a, &b);
			int k = (int)(log(b - a + 1.0) / log(2.0));
			int maxsum = max(FMAX[a][k], FMAX[b - (1 << k) + 1][k]);
			int minsum = min(FMIN[a][k], FMIN[b - (1 << k) + 1][k]);
			printf("%d\n", maxsum - minsum);
		}
	}
	return 0;
}


你可能感兴趣的:(数据结构)