L3-002 堆栈 树状数组+二分答案

来源:互联网 发布:js继承 编辑:程序博客网 时间:2024/06/09 23:03

题目详情点击这里

思路:用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;elsel = m+1;}printf("%d\n",l);}}return 0; } 



0 0
原创粉丝点击