POJ 3264 Balanced Lineup(线段树维护区间最大值最小值)

题目链接:http://poj.org/problem?id=3264

解题思路:

线段树维护一个区间的最大值,最小值,初始分别赋值为很小的负数,很大的正数

代码版本1:

#include
#include
#include
#define ll long long
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define mid int m = l+r>>1
#define tl tree[rt<<1]
#define tr tree[rt<<1|1]
#define inf 0x3f3f3f3f

using namespace std;

const int N = 5e4+5;

struct node
{
    int minn,maxx;
    node(){minn=inf;maxx=-inf;}
}tree[N<<2];

node cmp(node a,node b)
{
    node temp;
    temp.maxx = max(a.maxx,b.maxx);
    temp.minn = min(a.minn,b.minn);
    return temp;
}

void push_up(int rt)
{
    tree[rt].maxx = max(tl.maxx,tr.maxx);
    tree[rt].minn = min(tl.minn,tr.minn);
}

node query(int L,int R,int rt,int l,int r)
{
    if (L<=l && r<=R){
        return tree[rt];
    }
    mid;
    node ans;
    if (L<=m) ans = cmp(ans,query(L,R,lson));
    if (R>m ) ans = cmp(ans,query(L,R,rson));
    return ans;
}

void build(int rt,int l,int r)
{
    if (l==r){
        int x;
        scanf("%d",&x);
        tree[rt].maxx = tree[rt].minn = x;
        return ;
    }
    mid;
    build(lson);
    build(rson);
    push_up(rt);
}

int main()
{
    int n,q;
    scanf("%d %d",&n,&q);
    build(1,1,n);
    int x,y;
    while (q--){
        scanf("%d %d",&x,&y);
        node sb = query(x,y,1,1,n);
        printf("%d\n",sb.maxx-sb.minn);
    }
    return 0;
}

代码版本2:

#include
#include
#include
#include
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define ll long long
#define mid int m=l+r>>1
#define maxl maxx[rt<<1]
#define maxr maxx[rt<<1|1]
#define minl minn[rt<<1]
#define minr minn[rt<<1|1]
#define INF 0x3f3f3f3f
using namespace std;

const int N = 5e4+5;

int maxx[N<<2],minn[N<<2],Max,Min;

void push_up(int rt)
{
    maxx[rt] = max(maxl,maxr);
    minn[rt] = min(minl,minr);
}

void build(int rt,int l,int r)
{
    if (l==r){
        scanf("%d",&maxx[rt]);
        minn[rt] = maxx[rt];
        return ;
    }
    mid;
    build(lson);
    build(rson);
    push_up(rt);
}

void query(int L,int R,int rt,int l,int r)
{
    if (L<=l && r<=R){
        Max = max(Max,maxx[rt]);
        Min = min(Min,minn[rt]);
        return ;
    }
    mid;
    if (L<=m) query(L,R,lson);
    if (R>m)  query(L,R,rson);
}

int main()
{
    int n,q,l,r;
    while (~scanf("%d %d",&n,&q)){
        build(1,1,n);
        while (q--){
            Max = -INF;
            Min = INF;
            scanf("%d %d",&l,&r);
            query(l,r,1,1,n);
            printf("%d\n",Max-Min);
        }
    }
    return 0;
}

 

你可能感兴趣的:(线段树)