题目意思很简单,求解给定一个区间中的最小与最大,但此题不适合用线段树解,因为区间动态的变化。用单调队列比较适合,也可以用2个堆来维护,一个维护最大,一个维护最小。用单调队列实现的程序如下:
/*
ID: csuchenan
PROG: POJ 2823
LANG: C++
*/
#include<stdio.h>
const int maxn = 1000000 ;
#define INF -1u>>1
struct Node{
int pos ;
int val ;
}q[maxn + 5] ;
int key[maxn + 5] ;
void init() ;
void work() ;
int n ;//number of the sequence
int k ;//the
int main(int argc , char * argv[]){
init() ;
work() ;
return 0 ;
}
void init(){
scanf("%d %d" , &n , &k) ;
for(int i = 1 ; i <= n ; i ++){
scanf("%d" , &key[i]) ;
}
if(n<= k){
k = n ;
}
return ;
}
void work(){
int i ;
int j ;
int front ;
int rear ;
front = 1 ;
rear = 0 ;
q[0].val = INF ;
q[0].pos = 0 ;
//caculate the min of the k number
bool first = 0 ;
for(i = 1 ; i < k ; i ++){
//add data to the min queue
while(front <= rear && q[rear].val > key[i]){
rear -- ;
}
rear ++ ;
q[rear].val = key[i] ;
q[rear].pos = i ;
}
for(i = k ; i <= n ; i ++){
while(front <= rear && q[rear].val > key[i]){
rear -- ;
}
rear ++ ;
q[rear].val = key[i] ;
q[rear].pos = i ;
while(front <= rear && q[front].pos <= i - k){
front ++ ;
}
if(first)
printf(" ") ;
printf("%d" , q[front].val) ;
first = 1 ;
}
printf("\n") ;
first = 0 ;
q[0].val = -INF ;
q[0].pos = 0 ;
front = 1 ;
rear = 0 ;
for(i = 1 ; i < k ; i ++){
//add the data to the queue
while(front <= rear && q[rear].val < key[i]){
rear -- ;
}
rear ++ ;
q[rear].val = key[i] ;
q[rear].pos = i ;
}
for(i = k ; i <= n ; i ++){
while(front <= rear && q[rear].val < key[i]){
rear -- ;
}
rear ++ ;
q[rear].val = key[i] ;
q[rear].pos = i ;
while(front <= rear && q[front].pos <= i - k){
front ++ ;
}
if(first)
printf(" ") ;
printf("%d" , q[front].val) ;
first = 1 ;
}
return ;
}
用优先队列来维护的方式如下:
/*
ID : csuchenan
PROG: POJ 2823
LANG: c++
use the priority_queue
*/
#include<stdio.h>
#include<queue>
using namespace std ;
const int maxn = 1000000 ;
struct Node{
int pos ;
int val ;
} ;
struct cmpless{
bool operator()(Node a , Node b){
return a.val > b.val ;
}
};
struct cmpgreat{
bool operator()(Node a , Node b){
return a.val < b.val ;
}
};
int key[maxn+5] ;
int res[maxn+5] ;
void init() ;
void work() ;
int n ;
int k ;
int main(){
init() ;
work() ;
return 0 ;
}
void init(){
scanf("%d %d" , &n , &k) ;
for(int i = 1 ; i <= n ; i ++){
scanf("%d" , &key[i]) ;
}
return ;
}
void work(){
int i ;
int j ;
priority_queue<Node , vector<Node> , cmpless> qmin ;
priority_queue<Node , vector<Node> , cmpgreat> qmax ;
Node a ;
for(i = 1 ; i < k ; i ++){
a.val = key[i] ;
a.pos = i ;
qmin.push(a) ;
qmax.push(a) ;
}
bool first = 0 ;
int p ;
p = 0 ;
for(i = k ; i <= n ; i ++){
a.val = key[i] ;
a.pos = i ;
qmin.push(a) ;
qmax.push(a) ;
j = i - k ;
while(qmin.top().pos <= j){
qmin.pop() ;
}
if(first){
printf(" ");
}
printf("%d" , qmin.top().val) ;
first = 1 ;
while(qmax.top().pos <= j){
qmax.pop() ;
}
res[p++] = qmax.top().val ;
}
printf("\n") ;
first = 0 ;
for(i = 0 ; i < p ; i ++){
if(first)
printf(" ") ;
printf("%d" , res[i]) ;
first = 1 ;
}
return ;
}