POJ 2364 Balanced Lineup
原创
©著作权归作者所有:来自51CTO博客作者Stven_King的原创作品,请联系作者获取转载授权,否则将追究法律责任
题目链接: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
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;
}