思路:
用multset(允许重复出现的set集合)维护两个堆l、r,l存前半段数字,r存后半段数字,当栈中元素数为奇数l.size() == r.size,当栈中元素数为偶数时l.size() == r.size + 1,*(l.end() - 1)即为中位数,注意:每次判断时都要先验证堆或栈中是否为空。
代码:
#include <bits/stdc++.h>
#define fastio ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL)
#define debug(a) cout << "debug : " << (#a) << " = " << a << endl
using namespace std;
typedef long long ll;
typedef pair<int, string> PII;
const int N = 1e4 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int mod = 998244353;
multiset<int> l, r;
stack<int> sk;
void adjust()
{
while (l.size() < r.size())
{
int t = *r.begin();
r.erase(r.begin());
l.insert(t);
}
while (l.size() - 1 > r.size())
{
auto it = l.end();
it--;
r.insert(*it);
l.erase(it);
}
}
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
string op;
cin >> op;
if (op == "Pop")
{
if (sk.empty())
cout << "Invalid" << endl;
else
{
int del = sk.top();
cout << del << endl;
sk.pop();
if (r.size() && del < *(r.begin()) && l.size()) //这里判断时需要验证一下两堆中是否有元素
l.erase(l.find(del));
else if (r.size())
r.erase(r.find(del));
adjust();
}
}
else if (op == "PeekMedian")
{
if (sk.empty())
cout << "Invalid" << endl;
else
{
auto it = l.end();
it--;
cout << *it << endl;
}
}
else
{
int x;
cin >> x;
sk.push(x);
if (r.empty() || x < *r.begin())
l.insert(x);
else
r.insert(x);
adjust();
}
}
return 0;
}