poj 3264 Balanced Lineup(RMQ)

来源:互联网 发布:linux重新挂载分区 编辑:程序博客网 时间:2024/06/12 21:00

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


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


【ST算法】:

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

Sparse TableST)算法是基于倍增思想设计的O(Nlog2N) O(1)的在线算法
算法记录从每个元素开始的连续的长度为2k区间中元素的最小值,并以在常数时间内解决询问
定义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对于长度为2k的区间的最大值,可以由两个长度为2k-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 longint 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;}