POJ3264:Balanced Lineup

来源:互联网 发布:安徽易众网络 编辑:程序博客网 时间:2024/05/24 04:43

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 -99999999struct 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) ;}}