关闭

POJ-3264 Balanced Lineup【RMQ】

2529人阅读 评论(0) 收藏 举报

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

题目大意:

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

解题思路:

我是用RMQ写的。

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

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


代码如下:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<climits>
#include<cmath>
#include<algorithm>
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;
}


2
1

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    座右铭:
    时间并不会因为你的迷茫和迟疑而停留,就在你看这篇文章的同时,不知道有多少人在冥思苦想,在为算法废寝忘食,不知道有多少人在狂热地拍着代码,不知道又有多少提交一遍又一遍地刷新着OJ的status页面……
    没有谁生来就是神牛,而千里之行,始于足下!
    个人资料
    • 访问:1813060次
    • 积分:17878
    • 等级:
    • 排名:第529名
    • 原创:317篇
    • 转载:51篇
    • 译文:0篇
    • 评论:588条
    最新评论