题意:给出初始化的区间值,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 ;
}