POJ 3264 Balanced Lineup -- RMQ或线段树

一段区间的最值问题,用线段树或RMQ皆可。两种代码都贴上:又是空间换时间。。

RMQ 解法:(8168KB 1625ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 50003

int a[N],dmin[N][20],dmax[N][20],n;

void RMQ_init()
{
    int i,j;
    for(i=1;i<=n;i++)
        dmin[i][0] = dmax[i][0] = a[i];
    for(j=1;(1<<j)<=n;j++)
    {
        for(i=1;i+(1<<j)-1<=n;i++)
        {
            dmin[i][j] = min(dmin[i][j-1],dmin[i+(1<<(j-1))][j-1]);
            dmax[i][j] = max(dmax[i][j-1],dmax[i+(1<<(j-1))][j-1]);
        }
    }
}

int RMQ(int l,int r)
{
    int k = 0;
    while((1<<(k+1)) <= r-l+1)
        k++;
    return max(dmax[l][k],dmax[r-(1<<k)+1][k]) - min(dmin[l][k],dmin[r-(1<<k)+1][k]);
}

int main()
{
    int q,i;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        RMQ_init();
        while(q--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            if(l>r)
                swap(l,r);
            printf("%d
",RMQ(l,r));
        }
    }
    return 0;
}
View Code

线段树解法:(1172KB  2297ms)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 50003

struct node
{
    int maxi,mini;
}tree[4*N];

void pushup(int rt)
{
    tree[rt].maxi = max(tree[2*rt].maxi,tree[2*rt+1].maxi);
    tree[rt].mini = min(tree[2*rt].mini,tree[2*rt+1].mini);
}

void build(int l,int r,int rt)
{
    if(l == r)
    {
        scanf("%d",&tree[rt].maxi);
        tree[rt].mini = tree[rt].maxi;
        return;
    }
    int mid = (l+r)/2;
    build(l,mid,2*rt);
    build(mid+1,r,2*rt+1);
    pushup(rt);
}

int query_max(int l,int r,int aa,int bb,int rt)
{
    if(aa>r || bb<l)
        return -100000;
    if(aa<=l && bb>=r)
        return tree[rt].maxi;
    int mid = (l+r)/2;
    return max(query_max(l,mid,aa,bb,2*rt),query_max(mid+1,r,aa,bb,2*rt+1));
}

int query_min(int l,int r,int aa,int bb,int rt)
{
    if(aa>r || bb<l)
        return 100000000;
    if(aa<=l && bb>=r)
        return tree[rt].mini;
    int mid = (l+r)/2;
    return min(query_min(l,mid,aa,bb,2*rt),query_min(mid+1,r,aa,bb,2*rt+1));
}

int main()
{
    int n,q,i;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        build(1,n,1);
        for(i=1;i<=q;i++)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            if(l>r)
                swap(l,r);
            printf("%d
",query_max(1,n,l,r,1)-query_min(1,n,l,r,1));
        }
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/whatbeg/p/3582486.html