码迷,mamicode.com
首页 > 其他好文 > 详细

POJ3264 Balanced Lineup

时间:2016-10-05 07:05:54      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:

题解:

可以当做是RMQ中的ST算法的模板题

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
using namespace std;
#define pb push_back
#define mp make_pair
#define se second
#define fs first
#define ll long long
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define ls o<<1
#define rs o<<1|1
#define SZ(x) ((int)(x).size())
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++)
typedef pair<int,int> P;
const double eps=1e-9;
const int maxn=50100;
const int N=1e9;
const int mod=1e9+7;

ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
    while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
    return x*f;
}
//-----------------------------------------------------------------------------

int w[maxn];
int n,q,l,r;
int mi[maxn][20],mx[maxn][20];//mi[j][i]表示以j开头,长度为2^i次方的最小值,mx同理 

void rmq_init(){
    //预处理以出每个数为开头..范围依次为2^0,2^1.....中的极值 
    for(int i=1;i<=n;i++) mi[i][0]=mx[i][0]=w[i];
    int m=(int)(log(n*1.0)/log(2.0));//m表示2^i的中的i的最大值 
    for(int i=1;i<=m;i++)
    for(int j=1;j<=n;j++){
        mi[j][i]=mi[j][i-1];//mi[j][i]的最小值可由mi[j][i-1]和mi[j+(1<<(i-1)][i-1]而来,就是分为一半 
        if(j+(1<<(i-1))<=n) mi[j][i]=min(mi[j][i],mi[j+(1<<(i-1))][i-1]);
        mx[j][i]=mx[j][i-1];
        if(j+(1<<(i-1))<=n) mx[j][i]=max(mx[j][i],mx[j+(1<<(i-1))][i-1]);    
    }
}


//[l,r]的极值可以由[l,m],[m,r]两个范围求得
//只要满足l+2^k>=r-2^k+1即可
// 2^(k+1)>=r-l+1------>k>=log2(r-l+1)-1;
//1.当log2(r-l+1)为整数时,k取log(r-l+1)-1,也可以取log(r-l+1),也就是整个区间 
//2.当log2(r-l+1)不为整数时,k取log(r-l+1)-1的向上去整,也就是log(r-l+1)的向下取整
//综合1,2,直接去log2(r-l+1)的向下取整即可,也就是(int)(log2(r-l+1)) 
int rmq_max(int l,int r){
    int k=(int)(log((r-l+1)*1.0)/log(2.0));
    return max(mx[l][k],mx[r-(1<<k)+1][k]);//这里加1是因为,举个例子[1,8],范围为8,则8-8+1 
}

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


int main(){
    scanf("%d%d",&n,&q);
    for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    rmq_init();
    for(int i=1;i<=q;i++){
        scanf("%d%d",&l,&r);
        printf("%d\n",rmq_max(l,r)-rmq_min(l,r));
    }
    return 0;
}

 

POJ3264 Balanced Lineup

标签:

原文地址:http://www.cnblogs.com/byene/p/5931596.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!