poj3264 Balanced Lineup

线段树的基本题。询问给定区间内最大值与最小值的差。

分别建个最大堆和最小堆即可。

#include<stdio.h>
#include<string.h>
#include<iostream>
#define MAXD 1000001
using namespace std;
int N,Q,maxt[2*MAXD],mint[2*MAXD],a[MAXD],D;

int great(int a,int b)
{
    return a>b?a:b;
}

int small(int a,int b)
{
    return a<b?a:b;
}

int Qmax(int x,int y)
{
    int i=D+x-1,j=D+y+1,ans=0;
    for(;i^j^1;i>>=1,j>>=1)
    {
        if(~i&1)
        ans=great(ans,maxt[i^1]);
        if(j&1)
        ans=great(ans,maxt[j^1]);
    }
    return ans;
}
int Qmin(int x,int y)
{
    int i=D+x-1,j=D+y+1,ans=0x3f3f3f3f;
    for(;i^j^1;i>>=1,j>>=1)
    {
        if(~i&1)
        ans=small(ans,mint[i^1]);
        if(j&1)
        ans=small(ans,mint[j^1]);
    }
    return ans;
}
int main()
{
    //freopen("test.txt","r",stdin);
    scanf("%d%d",&N,&Q);
    for(D=1;D<N;D<<=1);
    int i;
    for(i=1;i<=N;i++)
    scanf("%d",&a[i]);
    memset(maxt,0,sizeof(maxt));
    for(i=1;i<=N;i++)
    maxt[D+i]=a[i];
    for(i=D-1;i>0;i--)
    maxt[i]=great(maxt[i<<1],maxt[i<<1|1]);
    memset(mint,0x3f,sizeof(mint));
    for(i=1;i<=N;i++)
    mint[D+i]=a[i];
    for(i=D-1;i>0;i--)
    mint[i]=small(mint[i<<1],mint[i<<1|1]);
    int x,y;
    for(i=1;i<=Q;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",Qmax(x,y)-Qmin(x,y));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/longlongagocsu/p/2889478.html