/*
题意:"I"表示输入数据,"Q"表示输出第k大数据
题解:优先队列,从大到小,队列中只需要k个元素。每次输出最小的即可
我用小顶堆实现,如果插入元素比tree[1]小,则直接舍掉。否则,更新。
*/
#include <iostream>
using namespace std;
const int nMax = 1000010;
int tree[nMax];
int n, k;
void build(int pos)//建树
{
int p = pos;
while(p != 1)
{
if(tree[p] < tree[p / 2])
{
int temp = tree[p];
tree[p] = tree[p / 2];
tree[p / 2] = temp;
}
p = p / 2;
}
}
void update(int a)//替换顶点后的更新
{
int p = 1;
int son;
while(2 * p <= k)
{
if(2 * p == k || tree[2 * p] < tree[2 * p + 1])
son = 2 * p;
else
son = 2 * p + 1;
if(tree[p] <= tree[son])
break;
else
{
int temp = tree[p];
tree[p] = tree[son];
tree[son] = temp;
p = son;
}
}
}
int main()
{
//freopen("e://data.in", "r", stdin);
while(scanf("%d%d", &n, &k) != EOF)
{
char opr[10];
int a;
int i;
for(i = 1; i <= n; ++ i)
{
scanf("%s", opr);
if(opr[0] == 'I')
{
scanf("%d", &a);
if(i <= k)
{
tree[i] = a;
build(i);
}
else if(a > tree[1])
{
tree[1] = a;
update(a);
}
}
else
printf("%d\n", tree[1]);
}
}
return 0;
}
STL实现:
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int n, k;
int main()
{
while(scanf("%d%d", &n, &k) != EOF)
{
//priority_queue<int, vector<int>, greater<int>> q;
priority_queue<int, vector<int>, greater<int> > q;//仔细比对与上面程序有什么不一样,两个>>不能连到一起
int i;
char opr[10];
int a;
for(i = 0; i < n; ++ i)
{
scanf("%s", opr);
if(opr[0] == 'I')
{
scanf("%d", &a);
/*
if(q.size() < k)
q.push(a);
else if(a > q.top())
{
q.pop();
q.push(a);
}*/
q.push(a);//程序这样写更好一些
if(q.size() > k)
q.pop();
}
else if(opr[0] == 'Q')
{
printf("%d\n", q.top());
}
}
}
return 0;
}