思路:用std::stack来表示题目中说的栈,现在关键问题就是如何找到中位数。
可以用二分答案+树状数组的方法
由于每个元素最大不超过1e5,因此开一个大小为1e5的树状数组来存储不超过x的数有多少个
每次push一个元素,都把以它为下标的树状数组位置+1,pop就相当于-1
这样的话sum(x)的含义就是栈中不超过x的数有多少个。然后就可以用二分的方法把答案确定出来了。
因为中位数x肯定要满足sum(x) >= N/2 或者sum(x) >= (N+1)/2
以前太菜了,现在看这道题目,感觉不难
代码:
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
const int MAX = 1e5;
stack<int> stk;
int bitree[MAX + 10];
int N;
inline int lowbit(int x)
{
return x&(-x);
}
void add(int pos,int x)
{
while(pos <= MAX)
{
bitree[pos] += x;
pos += lowbit(pos);
}
}
int sum(int pos)
{
int res = 0;
while(pos > 0)
{
res += bitree[pos];
pos -= lowbit(pos);
}
return res;
}
bool check(int x,int size)
{
if(N&2 == 0)
return sum(x) >= size/2;
else return sum(x) >= (size+1)/2;
}
int main()
{
scanf("%d",&N);
char ops[20];
for(int i = 0;i < N;i++){
scanf("%s",ops);
if(ops[1] == 'o')
{
if(stk.empty())
puts("Invalid");
else{
int val = stk.top();stk.pop();
add(val,-1);
printf("%d\n",val);
}
}
else if(ops[1] == 'u')
{
int val;scanf("%d",&val);
stk.push(val);
add(val,1);
}
else
{
if(stk.empty()){puts("Invalid");continue;}
int l = 0,r = MAX;
while(l < r)
{
int m = (l+r)/2;
if(check(m,stk.size()))
r = m;
else
l = m+1;
}
printf("%d\n",l);
}
}
return 0;
}