POJ 3264 Balanced Lineup(线段树+区间最值查询RMQ)

题意:
查询一个区间的最大值与最小值之差。

思路:
build构造线段树
query_mi查询区间最小值
query_ma查询区间最大值
再用最大值减去最小值得出结果。
注意:线段树要开四倍

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>

using namespace std;
int n,m,a[50005];

struct node
{
    int l,r,ma,mi;
}tree[50005*4];

void push_up(int id)
{
    tree[id].ma=max(tree[id*2].ma,tree[id*2+1].ma);
    tree[id].mi=min(tree[id*2].mi,tree[id*2+1].mi);
}
void build(int id,int l,int r)
{
    tree[id].l=l;
    tree[id].r=r;
    if(l==r)
    {
        tree[id].ma=tree[id].mi=a[l];
        return;
    }
    int mid=l+(r-l)/2;
    build(id*2,l,mid);
    build(id*2+1,mid+1,r);
    push_up(id);
}
int query_mi(int id,int l,int r)
{
    int L=tree[id].l,R=tree[id].r;
    if(l<=L&&R<=r)
    {
        return tree[id].mi;
    }
    if(l>R||r<L)
        return 1000005;
    int ans=1000005;
    if(tree[id*2].r>=l)
    {
        ans=min(ans,query_mi(id*2,l,r));
    }
    if(tree[id*2+1].l<=r)
    {
        ans=min(ans,query_mi(id*2+1,l,r));
    }
    return ans;
}
int query_ma(int id,int l,int r)
{
    int L=tree[id].l,R=tree[id].r;
    if(l<=L&&R<=r)
    {
        return tree[id].ma;
    }
    if(l>R||r<L)
        return 0;
    int ans=0;
    if(tree[id*2].r>=l)
    {
        ans=max(ans,query_ma(id*2,l,r));
    }
    if(tree[id*2+1].l<=r)
    {
        ans=max(ans,query_ma(id*2+1,l,r));
    }
    return ans;
}
int main()
{
    int x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    build(1,1,n);
    while(m--)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",query_ma(1,x,y)-query_mi(1,x,y));
    }
    return 0;
}

发布了19 篇原创文章 · 获赞 0 · 访问量 183

猜你喜欢

转载自blog.csdn.net/qq_43032263/article/details/104420898