单调增或减的队列,作用于广告印刷、动态规划等。
(单调增为例)
1、入队时,从队尾向前扫描,直到找到队内某个元素小于它,把它放在这个元素的后面,将它作为队尾,即删除队内比它大的所有元素。
它入队比所要删除的元素晚,证明它的位置一定大于所要删除元素的位置,根据这一点,我们可以推出:
在以后的选择中,当所要删除元素的位置在所要找的区间时,它也一定在所要找的区间内。
而它又比所要删除元素小,所以它一定比所要删除元素更优。
所以它的入队意味着所要删除的元素已经失去了价值,故可以删除。
2、出队时,如果队首元素的位置不在所要找的区间内,那么就把下个元素作为队首,即删除原队列的队首。
此时下个元素一定在所要找的区间内。
假设上次查找的区间为[a,a+k-1],那么经过上次出队后,队首元素的位置最坏情况下是a,那么它后面的元素的位置一定满足p>=a+1,
所以它后面的元素一定在这次要找的区间[a+1,a+k]中。
#define maxn 100000+10
int num[maxn];
int max_que[maxn]; //记录元素的位置
int get_que(int f,int r,int x){ //二分
int mid;
while( f <= r ){
mid = ( f + r ) / 2;
if( num[max_que[mid]] == num[x] )
return mid;
if( num[max_que[mid]] > num[x] )
r = mid - 1;
else
f = mid + 1;
}
return r;
}
int get_que(int f,int r,int x){ //非二分
while( f < r && num[x] <= num[max_que[r]] )
r--;
return r;
}