http://poj.org/problem?id=3264
初次使用线段树解题,题目意思很清楚,查询区间[p ,q]中的最小数与最大数,然后输出二者之差。采用线段树解决,问题要简单的多,建线段树,然后插入,查询即可。在设计节点的时候根据题意除了要包含基本的元素外,还要包含该段元素中最小的,最大的。
程序如下:
#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std ;
#define MY_MIN 99999999
#define MY_MAX -99999999
struct Node
{
int left ;
int right ;
int nMin ;
int nMax ;
}node[600000] ;
void build(int left , int right , int step) ;
void insert(int left , int right , int step) ;
void query(int left , int right , int step) ;
int n ;
int m ;
int nMin ;
int nMax ;
int main()
{
int i ;
int j ;
int p ;
int q ;
scanf("%d %d" , &n , &m) ;
build(1 , n , 0) ;
i = 1 ;
while(i <= n)
{
scanf("%d" , &p) ;
insert(i , p , 0) ;
i ++ ;
}
while(m--)
{
scanf("%d %d" , &p , &q) ;
nMin = MY_MIN ;
nMax = MY_MAX ;
query(p , q , 0) ;
printf("%d\n" , nMax - nMin) ;
}
return 0 ;
}
void build(int left , int right , int step)
{
node[step].left = left ;
node[step].right = right ;
node[step].nMin = MY_MIN ;
node[step].nMax = MY_MAX ;
int pl = step * 2 + 1 ;
int pr = step * 2 + 2 ;
if(left != right)
{
int mid = (left + right)/2 ;
build(left , mid , pl) ;
build(mid + 1 , right , pr) ;
}
}
void insert(int left , int right , int step)
{
if(node[step].left == left && node[step].right == left)
{
node[step].nMin = node[step].nMax = right ;
return ;
}
//node[step].nMin = node[step].nMin > right ? right : node[step].nMin ;
//node[step].nMax = node[step].nMax > right ? node[step].nMax : right ;
node[step].nMin = min(right , node[step].nMin ) ;
node[step].nMax = max(right , node[step].nMax ) ;
int mid = (node[step].left + node[step].right)/2 ;
int pl = step * 2 + 1 ;
int pr = step * 2 + 2 ;
if(mid < left)
insert(left , right , pr) ;
else if(mid >= left)
insert(left , right , pl) ;
}
void query(int left , int right , int step)
{
if(node[step].nMin >= nMin && node[step].nMax <= nMax)
return ;
if(node[step].left == left && node[step].right == right )
{
nMin = min(node[step].nMin , nMin) ;
nMax = max(node[step].nMax , nMax) ;
return ;
}
int mid = (node[step].left + node[step].right) / 2 ;
int pl = step * 2 + 1 ;
int pr = step * 2 + 2 ;
if(mid < left)
query(left , right , pr) ;
else if(mid >= right)
query(left , right , pl) ;
else
{
query(left , mid , pl) ;
query(mid + 1 , right , pr) ;
}
}