poj 3264 Balanced Lineup(RMQ)

【题目大意】:给出一些数,求出区间内最大值减去最小值的差值。


【解题思路】:经典的RMQ问题啊,用ST算法。&&还有线段树写法,改天写一下。


【ST算法】:

下面简单介绍一下ST算法:

Sparse Table ST )算法是基于倍增思想设计的 O(Nlog 2 N)  O(1) 的在线算法
算法记录从每个元素开始的连续的长度为 2 k 区间中元素的最小值,并以在常数时间内解决 询问
定义 rmq[i][k] 为区间 [i,i+(2^k)-1] 的最值,也即表 示从 i 开始,长度为 2^k 的区间的最值
对于查询RMQAij),区间[i,j]的最值= max(rmq[i][k],rmq[j-(1<<k)+1][k]) ,其中2^k是最接近区间长度的2的幂,k =log(b-a+1.0)/log(2.0);
如果我们事先计算了所有的 rmq[i][k] ,则由已经计算的 结果就可以在 O(1) 的时间内解决询问
l 对于长度为 2 k 的区间的最大值,可以由两个长度为 2 k-1 的区间的最大值得到 , rmq[i][k] =  max( rmq[i][k-1] , rmq[i+2^(k-1)][k-1] )

【代码】:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <string>
#include <cctype>
#include <map>
#include <iomanip>
                   
using namespace std;
                   
#define eps 1e-8
#define pi acos(-1.0)
#define inf 1<<30
#define pb push_back
#define lc(x) (x << 1)
#define rc(x) (x << 1 | 1)
#define lowbit(x) (x & (-x))
#define ll long long

int n,m,x,y;
int a[50100];
int rmq_min[50100][16],rmq_max[50100][16];

void init_rmq(){
    for(int i=1;i<=n;i++)  { rmq_max[i][0]=rmq_min[i][0]=a[i]; }
    for(int k=1;(1<<k)<=n;k++)
    for(int i=1;(i+(1<<k)-1)<=n;i++){
        rmq_max[i][k]=max(rmq_max[i][k-1],rmq_max[i+(1<<(k-1))][k-1]);
        rmq_min[i][k]=min(rmq_min[i][k-1],rmq_min[i+(1<<(k-1))][k-1]);
    }
}


int search_rmq(int l,int r){
    int k=(int)(log(r-l+1.0)/log(2.0));
    return max(rmq_max[l][k],rmq_max[r-(1<<k)+1][k])-min(rmq_min[l][k],rmq_min[r-(1<<k)+1][k]);
}


int main() {
    memset(rmq_min,0,sizeof(rmq_min));
    memset(rmq_max,0,sizeof(rmq_max));
    scanf("%d%d",&n,&m);
    for (int i=1; i<=n; i++) scanf("%d",&a[i]);
    init_rmq();
    for (int i=1; i<=m; i++){
        scanf("%d%d",&x,&y);
        printf("%d\n",search_rmq(x,y));
    }
    
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值