仿照:http://www.2cto.com/kf/201106/92643.html
题意:给出两种操作:ADD(x),将x添加到有序列表中;GET()返回全局迭代器所指的值,其中迭代器在GET操作后会自添加1
题解:大顶堆和小顶堆。
其中,对于序列S[1..n],及表示迭代器位置的index,大顶堆维护排序后的S[1..index-1],小顶堆维护排序后的S[index..n],
例如S[1..n] = 1,2,3,4,5,6,7,index = 4,则大顶堆为{1,2,3},小顶堆为{4,5,6,7}为什么要这样维护呢?因为当小堆最小的元素都大于大堆最大的元素时,那么序列中排第index个数就是小堆最小的数了。
我们假设第k趟GET()后,有以下情景(GET后k自动加1):大顶堆:S[1..k],堆顶元素为S[k],小顶堆:S[k+1,n],堆顶元素为S[k+1],然后每当添加一个元素newE时,先添加到大顶堆中,这时如果出现大顶堆数大于小顶堆的数时,理应交换。
#include <iostream> #include <queue> using namespace std; #define M 30005 int array[M]; priority_queue< int,vector<int>,less<int> > maxHeap; priority_queue< int,vector<int>,greater<int> > minHeap; int main() { int n, m, i; scanf("%d%d",&n,&m); for ( i = 0; i < n; ++i ) scanf("%d",array+i ); int oper = 0, k = 0, t1, t2; for ( i = 0; i < m; ++i ) { scanf("%d",&oper); while ( k < oper ) { minHeap.push ( array[k] ); if ( ! maxHeap.empty() && minHeap.top() < maxHeap.top() ) { t1 = minHeap.top(); minHeap.pop(); t2 = maxHeap.top(); maxHeap.pop(); maxHeap.push(t1); minHeap.push(t2); } ++k; } printf("%d\n",minHeap.top()); maxHeap.push ( minHeap.top() ); minHeap.pop(); } return 0; }
下面是手工实现堆:
#include <iostream> using namespace std; const int M = 30005; int array[M]; struct min_Heap { int hp[M], size; void siftDown ( int start, int m ) { int i = start, j = 2 * i + 1; int temp = hp[i]; while ( j <= m ) { if ( j < m && hp[j] > hp[j+1] ) ++j; if ( temp <= hp[j] ) break; else { hp[i] = hp[j]; i = j; j = j * 2 + 1; } } hp[i] = temp; } void siftUp ( int start ) { int j = start, i = ( j - 1 ) / 2; int temp = hp[j]; while ( j > 0 ) { if ( temp >= hp[i] ) break; else { hp[j] = hp[i]; j = i; i = ( i - 1 ) / 2; } } hp[j] = temp; } void insert ( const int x ) { hp[size] = x; siftUp ( size ); size++; } void del () { hp[0] = hp[size-1]; size--; siftDown ( 0, size-1 ); } int getSize () { return size; } } minHeap; struct max_Heap { int hp[M], size; void siftDown ( int start, int m ) { int i = start, j = 2 * i + 1; int temp = hp[i]; while ( j <= m ) { if ( j < m && hp[j] < hp[j+1] ) ++j; if ( temp >= hp[j] ) break; else { hp[i] = hp[j]; i = j; j = j * 2 + 1; } } hp[i] = temp; } void siftUp ( int start ) { int j = start, i = ( j - 1 ) / 2; int temp = hp[j]; while ( j > 0 ) { if ( temp <= hp[i] ) break; else { hp[j] = hp[i]; j = i; i = ( i - 1 ) / 2; } } hp[j] = temp; } void insert ( const int x ) { hp[size] = x; siftUp ( size ); size++; } void del () { hp[0] = hp[size-1]; size--; siftDown ( 0, size-1 ); } int getSize () { return size; } } maxHeap; int main() { int n, m, i; scanf("%d%d",&n,&m); for ( i = 0; i < n; ++i ) scanf("%d",array+i); int oper, t1, t2, k = 0; minHeap.size = maxHeap.size = 0; for ( i = 0; i < m; ++i ) { scanf("%d",&oper); while ( k < oper ) { minHeap.insert(array[k]); if ( maxHeap.getSize() != 0 && minHeap.hp[0] < maxHeap.hp[0] ) { t1 = minHeap.hp[0]; minHeap.del(); t2 = maxHeap.hp[0]; maxHeap.del(); minHeap.insert(t2); maxHeap.insert(t1); } ++k; } printf("%d\n",minHeap.hp[0]); maxHeap.insert(minHeap.hp[0]); minHeap.del(); } return 0; }