栈
https://www.acwing.com/problem/content/description/1545/
#include <iostream>
#include <cstring>
#include <set>
#include <stack>
using namespace std;
stack<int> stk;
multiset<int> up, down;
void adjust()
{
while (up.size() > down.size())
{
down.insert(*up.begin());
up.erase(up.begin());
}
while (down.size() > up.size() + 1)
{
auto it = down.end();
it -- ;
up.insert(*it);
down.erase(it);
}
}
int main()
{
int n;
scanf("%d", &n);
char op[20];
while (n -- )
{
scanf("%s", op);
if (strcmp(op, "Push") == 0)
{
int x;
scanf("%d", &x);
stk.push(x);
if (up.empty() || x < *up.begin()) down.insert(x);
else up.insert(x);
adjust();
}
else if (strcmp(op, "Pop") == 0)
{
if (stk.empty()) puts("Invalid");
else
{
int x = stk.top();
stk.pop();
printf("%d\n", x);
auto it = down.end();
it -- ;
if (x <= *it) down.erase(down.find(x));
else up.erase(up.find(x));
adjust();
}
}
else
{
if (stk.empty()) puts("Invalid");
else
{
auto it = down.end();
it -- ;
printf("%d\n", *it);
}
}
}
return 0;
}
树状数组的做法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;
const int N = 100010;
int tr[N];
stack<int> s;
int lowbit(int x)
{
return x & -x;
}
void add(int x, int c)
{
for(int i = x; i <= N; i += lowbit(i)) tr[i] += c;
}
int getsum(int x)
{
int sum = 0;
for(int i = x; i; i -= lowbit(i)) sum += tr[i];
return sum;
}
void PeekMedian()
{
int left = 1, right = N, k = (s.size() + 1) >> 1;
while(left < right)
{
int mid = (left + right) >> 1;
if(getsum(mid) >= k) right = mid;
else left = mid + 1;
}
printf("%d\n", left);
}
int main()
{
int n, temp;
scanf("%d", &n);
char str[15];
for(int i = 0; i < n; i ++ )
{
scanf("%s", str);
if(str[1] == 'u')
{
scanf("%d", &temp);
s.push(temp);
add(temp, 1);
}
else if(str[1] == 'o')
{
if(!s.empty())
{
add(s.top(), -1);
printf("%d\n", s.top());
s.pop();
}
else printf("Invalid\n");
}
else if(!s.empty()) PeekMedian();
else printf("Invalid\n");
}
return 0;
}