POJ 3264 Balanced Lineup

题意:给出初始化的区间值,m次查询。每次查询区间[a,b]的最大值-最小值


分析:线段树 更新: 无更新  查询:区间查询, 建立线段树的时候,每个结点存储左右子树的最大值和最小值,  查询时直接访问区间最大值和最小值,不需要查找到最低,查询时间复杂度O(logN)


//2384K	1594MS
#include <cstdio>
#include <cmath>
#include <iostream>
#include <climits>
#define MAXN 50010
#define L(X) ((X)<<1)
#define R(X) (((X)<<1) | 1 )
#define MID(X,Y) ( (X+Y) >> 1 )
#define MAX(X,Y) ( (X)>(Y) ? (X) : (Y) )
#define MIN(X,Y) ( (X)<(Y) ? (X) : (Y) )

struct node
{
    int left , right ;
    int min , max ;
}node[MAXN*4];
int num[MAXN] ;
int ans_min , ans_max ;

void Build_Tree ( int const left , int const right , int const n )
{
    node[n].left = left ;
    node[n].right = right ;
    if ( left < right )
    {
        int mid ;
        mid = MID(left,right) ;
        Build_Tree ( left , mid , L(n)) ;
        Build_Tree ( mid + 1 , right , R(n)) ;
    }
    else if ( left == right )
    {
        node[n].min = node[n].max =  num[left] ;
        return ;
    }
    node[n].min = MIN ( node[L(n)].min , node[R(n)].min ) ;
    node[n].max = MAX ( node[L(n)].max , node[R(n)].max ) ;
}

void Query ( int const left , int const right , int const n )
{
    if ( left == node[n].left && right == node[n].right )
    {
        ans_max = MAX ( node[n].max , ans_max ) ;
        ans_min = MIN ( node[n].min , ans_min ) ;
        return ;
    }
    int mid ;
    mid = MID ( node[n].left , node[n].right ) ; //注意,求的中值不是(left + right)/2,注意区间范围
    if ( left > mid )
    {
        Query ( left , right , R(n) ) ;
    }
    else  if ( right <= mid )
    {
        Query ( left , right , L(n) ) ;
    }
    else
    {
        Query ( left , mid , L(n) ) ;
        Query ( mid + 1 , right , R(n) ) ;
    }
}

int
main ( )
{
    int n , m ;
    scanf ("%d%d" , & n , & m ) ;
    for ( int i = 1 ; i <= n ; i ++ )
    {
        scanf ("%d" , & num[i] ) ;
    }
    Build_Tree ( 1 , n , 1 ) ;
    for ( int i = 1 ; i <= m ; i ++ )
    {
        ans_min = INT_MAX ;
        ans_max = 0 ;
        int left , right ;
        scanf ("%d%d" , & left , & right ) ;
        Query ( left , right , 1 ) ;
        printf ("%d\n" , ans_max - ans_min ) ;
    }
    return 0 ;

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值