POJ 3264 Balanced Lineup(RMQ求区间最值)

http://poj.org/problem?id=3264

题意:求某个区间最大值与最小值的差。


RMQ:利用动态规划的思想求区间最大值与最小值。又称为ST在线算法。
主要思想
F[i,j]表示从i开始,连续的 2^j个数中的最值。
1. 预处理:F[i, j]=max(F[i,j-1], F[i + (1<<(j-1)),j-1])。
2. 查询:找到i,j中间的k值,k = log2(j-i+1)。然后 ans = min/max(F[i,k],F[j-(1<< k)+1 , k];

模板Style:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long LL;

const int N = 50000 + 100;
int dp_max[N][20];
int dp_min[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)//!!!
            {
                dp_max[i][j] = max(dp_max[i][j-1],dp_max[i+(1<<(j-1))][j-1]);
                dp_min[i][j] = min(dp_min[i][j-1],dp_min[i+(1<<(j-1))][j-1]);
            }
        }
    }
    return;
}
int main()
{
    int n,m;
    while(~scanf("%d %d",&n,&m))
    {
        int x;
        for(int i=1;i<=n;i++)
            scanf("%d",&x),dp_max[i][0] = dp_min[i][0] = x;
        RMQ(n);
        while(m--)
        {
            int l,r;
            scanf("%d %d",&l,&r);
            int k = log10(r-l+1.0)/log10(2.0);//!!!
            int ans_max = max(dp_max[l][k],dp_max[r-(1<<k)+1][k]);
            int ans_min = min(dp_min[l][k],dp_min[r-(1<<k)+1][k]);
            cout<<ans_max - ans_min<<endl;
        }
    }
    return 0;
}

神模板加神题解:
http://blog.csdn.net/liang5630/article/details/7917702

http://blog.csdn.net/liang5630/article/details/7917706


博主很懒,什么都不想留下..

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值