仿照: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;
}