Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (-th smallest element if N is even, or (-th if N is odd.

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (≤). Then N lines follow, each contains a command in one of the following 3 formats:

Push key
Pop
PeekMedian

where key is a positive integer no more than 1.

Output Specification:

For each Push command, insert key into the stack and output nothing. For each Pop or PeekMediancommand, print in a line the corresponding returned value. If the command is invalid, print Invalidinstead.

Sample Input:

17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop

Sample Output:

Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid

数组数据是随时都在进行输入与删除的,让你实时反馈数组中的中位数:
使用分块思想
1、一般来说,为了达到高效率的目的,对一个有N个元素的有序序列来说,除最后一块外,其余每块中元素的个数都应当为 | √N | (此处为向下取整,方便程序实现),于是块数为[√N](此处为向上取整)。这样就把有序序列划分为[√N]块,其中每块中元素的个数不超过 | √N | 。
考虑到序列中的元素都是不超过105的非负整数,因此不妨设置一个hash数组table[100001],其中table[x]表示整数x的当前存在个数;
接着,借助分块思想,从逻辑上将0~10分为 | √(105 + 1) |= 317块,其中每块的元素个数为316。逻辑上进行分块的结果如下:
0,1,2.…,314,315为第0块;
316,317…,630,631为第1块。
99856,99857,…,100000为第316块。
这样分块有什么用呢?可以定义一个统计数组block[317],其中block[i]表示第i块中存在的元素个数。于是假如要新增一个元素x,就可以先计算出x所在的块号为x / 316,然后让block[x / 316]加1,表示该块中元素个数多了1;同时令table[x]加1,表示整数x的当前存
在个数多了1。
例如想要新增334这个元素,就可以通过334 / 316 = 1算出元素334所在的块号为1,然后令block[1]++,表示1号块增加了一个元素,并令table[334] + 1,表示元素334的存在个数多了1。
同理,如果想要删除一个元素x,只需要让block[x / 316]和table[x]都减1即可。显然,新增与删除元素的时间复杂度都是O(1)。
接着来看如何查询序列中第K大的元素是什么。
首先,从小到大枚举块号,利用block数组累加得到前i - 1块中存在的元素总个数,然后判断加入i号块的元素个数后元素总个数能否达到K。如果能,则说明第K大的数就在当前枚举的这个块中,此时只需从小到大遍历该块中的每个元素(其中i号块的第一个元素是i * 316),利用table数组继续累加元素的存在个数,直到总累计数达到K,则说明找到了序列第K大的数。显然整体思路是先用O(√N)的时间复杂度找到第K大的元素在哪一块,然后再用0(√N)的时间复杂度在块内找到这个元素,因此单次查询的总时间复杂度为0(√N)。

 #include <iostream>
#include <stack>
#include <string>
#include <cmath>
using namespace std;
int N, num, table[], block[];//数的个数,块中数的个数
int main()
{
cin >> N;
stack<int>s;
string str;
for (int i = ; i < N; ++i)
{
cin >> str;
if (str == "Pop")
{
if (s.size() > )
{
cout << s.top() << endl;
table[s.top()]--;
block[s.top() / ]--;
s.pop();
}
else
cout << "Invalid" << endl;
}
else if (str == "Push")
{
cin >> num;
s.push(num);
table[num]++;
block[num / ]++;
}
else
{
if (s.size() > )
{
int mid = s.size() % == ? s.size() / : (s.size() + ) / ;
int t = , k = ;
while (k + block[t] < mid) k += block[t++];
int num = t * ;
while (k + table[num] < mid)k += table[num++];
cout << num << endl;
}
else
cout << "Invalid" << endl;
}
}
return ;
}

最新文章

  1. Office2016打开doc字符间距过小
  2. servlet的九大内置对象
  3. RDLC系列之三 图片显示
  4. eclipse lua使用
  5. 华东交通大学2016年ACM“双基”程序设计竞赛 1009
  6. 《Java数据结构与算法》笔记-CH2有序数组
  7. windows 安装maven 环境
  8. Prime Ring Problem(搜索)
  9. 从lca到树链剖分 bestcoder round#45 1003
  10. Codeforces 626E Simple Skewness(暴力枚举+二分)
  11. activiti-用户与用户组
  12. python_装饰器
  13. mssqlserver on linux - Linux下尝鲜MSSQL-SERVER【微软大法棒棒哒】
  14. E212: Can&#39;t open file for writing Press ENTER or type command to continue
  15. 使用Anaconda3配置多版本Python虚拟开发环境
  16. Dockerize a .NET Core application
  17. string logo online customization
  18. 从exp入手分析漏洞
  19. 【BZOJ】1093: [ZJOI2007]最大半连通子图(tarjan+拓扑序)
  20. idea开发环境中maven控制台乱码解决

热门文章

  1. python的基本数据类型与字符串的操作
  2. QtCreator 生成动态库
  3. EJB(Enterprise JavaBean)科普
  4. python paramiko模块学习分享
  5. day24 面向对象设计part1
  6. 根据Cron表达式,通过Spring自带的CronSequenceGenerator类获取下次执行时间
  7. JavaScript实现几种常见的图形
  8. PyInstaller打包Python源文件为可执行程序exe
  9. css 图片高度自适应
  10. bzoj1010: [HNOI2008]玩具装箱toy——斜率优化