1057. Stack



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 (N/2)-th smallest element if N is even, or ((N+1)/2)-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 (<= 105). 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 105.

Output Specification:

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

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

题目大意:要求实现一个栈,除了基础的push和pop操作外,还要拥有查找中间数的操作
(PeekMedian),即n个栈中元素在排序后,该元素的大小排行为 (n+1)/2。因为可能存在大量的查找中间数的操作,所以必须找到快速的解决方法。



主要思想:解此题的过程可谓是一波三折。开始的想法很天真,在每次需要PeekMedian的时候,将栈中元素全部拷贝到一个辅助数组,然后对该数组进行排序,很容易找到中间值,时间复杂度为
O((n^2) lgn),很显然最后超时了。

由于题目说明数据范围为 1~100000,想到了用一个count[]数组来储存每一个数在栈中的个数,然后每一次通过遍历数组累积,当 S[i] = count[1] + count[2] + ... + count[i] >= (n+1)/2 的时候则找到中间值i,时间复杂度为 O(n^2)。

这样显然还会超时,在这个想法的基础上利用树状数组,这种数据结构可以很快的得出前 i 项和,从而可以利用二分查找来找到中间数。于是,push和pop操作时间复杂度为 O(lgn),PeekMedian的复杂度为 O(n (lgn)^2),问题解决。

#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string.h>
#define MAXN 100005
using namespace std;
int stack[MAXN]; //array of stack
int c[MAXN]; //BIT
int n = 0;
/*
functions of Binary Index Tree (BIT)
*/
int lowbit(int x) {
return x & (-x);
}
int get_sum(int x) {
int sum = 0;
for (int i = x; i > 0; i -= lowbit(i))
sum += c[i];
return sum;
}
void update(int x, int t) {
for (int i = x; i <= MAXN; i += lowbit(i))
c[i] += t;
} /*
operations of stack
*/
bool isEmpty() {
return n == 0;
}
void push(int key) {
stack[n++] = key;
update(key, 1);
}
int pop() {
int k = stack[--n];
update(k, -1);
return k;
}
int peek_median() {
int lo = 1, hi = MAXN;
int median = (n + 1) / 2; //use the binary search
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (median > get_sum(mid))
lo = mid + 1;
else // median <= get_sum(mid)
hi = mid - 1;
}
return lo;
} int main(void) {
int m;
char comment[11]; scanf("%d", &m);
getchar();
for (int i = 0; i < m; i++) {
gets(comment);
if (comment[1] == 'u') { //push
int key = atoi(comment+5);
push(key);
}
else if (comment[1] == 'o') { //pop
if(isEmpty()) {
printf("Invalid\n");
continue;
}
int t = pop();
printf("%d\n", t);
}
else { //peek median
if (isEmpty()) {
printf("Invalid\n");
continue;
}
int m = peek_median();
printf("%d\n", m);
}
} return 0;
}

PAT-1057 Stack (树状数组 + 二分查找)的更多相关文章

  1. 1057 Stack 树状数组

    Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...

  2. POJ 2182 Lost Cows (树状数组 && 二分查找)

    题意:给出数n, 代表有多少头牛, 这些牛的编号为1~n, 再给出含有n-1个数的序列, 每个序列的数 ai 代表前面还有多少头比 ai 编号要小的牛, 叫你根据上述信息还原出原始的牛的编号序列 分析 ...

  3. toj 4353 Estimation(树状数组+二分查找)

    Estimation 时间限制(普通/Java):5000MS/15000MS     运行内存限制:65536KByte总提交: 6            测试通过: 1 描述 “There are ...

  4. 树状数组+二分||线段树 HDOJ 5493 Queue

    题目传送门 题意:已知每个人的独一无二的身高以及排在他前面或者后面比他高的人数,问身高字典序最小的排法 分析:首先对身高从矮到高排序,那么可以知道每个人有多少人的身高比他高,那么取较小值(k[i], ...

  5. poj2182Lost Cows——树状数组快速查找

    题目:http://poj.org/problem?id=2182 从后往前确定,自己位置之前没有被确定的且比自己编号小的个数+1即为自己的编号: 利用树状数组快速查找,可另外开一个b数组,角标为编号 ...

  6. P2161 [SHOI2009]会场预约[线段树/树状数组+二分/STL]

    题目描述 PP大厦有一间空的礼堂,可以为企业或者单位提供会议场地.这些会议中的大多数都需要连续几天的时间(个别的可能只需要一天),不过场地只有一个,所以不同的会议的时间申请不能够冲突.也就是说,前一个 ...

  7. 牛客多校第3场 J 思维+树状数组+二分

    牛客多校第3场 J 思维+树状数组+二分 传送门:https://ac.nowcoder.com/acm/contest/883/J 题意: 给你q个询问,和一个队列容量f 询问有两种操作: 0.访问 ...

  8. POJ 2828 Buy Tickets (线段树 or 树状数组+二分)

    题目链接:http://poj.org/problem?id=2828 题意就是给你n个人,然后每个人按顺序插队,问你最终的顺序是怎么样的. 反过来做就很容易了,从最后一个人开始推,最后一个人位置很容 ...

  9. TZOJ 4602 高桥和低桥(二分或树状数组+二分)

    描述 有个脑筋急转弯是这样的:有距离很近的一高一低两座桥,两次洪水之后高桥被淹了两次,低桥却只被淹了一次,为什么?答案是:因为低桥太低了,第一次洪水退去之后水位依然在低桥之上,所以不算“淹了两次”.举 ...

随机推荐

  1. 华硕笔记本无法U盘启动,快捷键识别不了

    http://www.udaxia.com/upqd/8254.html 转载于:https://www.cnblogs.com/wanglinjie/p/10507888.html

  2. java中异常的处理

    异常分为运行时的异常和检测异常: java提供了两种异常机制.一种是运行时异常(RuntimeExepction),一种是检查式异常(checked execption). 运行时的异常就是在java ...

  3. Java中的集合Queue

    2019独角兽企业重金招聘Python工程师标准>>> package com.zhaogang.test; import org.junit.Test; import java.u ...

  4. #Week8 Advice for applying ML & ML System Design

    一.Evaluating a Learning Algorithm 训练后测试时如果发现模型表现很差,可以有很多种方法去更改: 用更多的训练样本: 减少/增加特征数目: 尝试多项式特征: 增大/减小正 ...

  5. [USACO1.3]虫洞wormhole

    题目描述 农夫约翰爱好在周末进行高能物理实验的结果却适得其反,导致N个虫洞在农场上(2<=N<=12,n是偶数),每个在农场二维地图的一个不同点. 根据他的计算,约翰知道他的虫洞将形成 N ...

  6. CodeForces-259B]Little Elephant and Magic Square

      Little Elephant loves magic squares very much. A magic square is a 3 × 3 table, each cell contains ...

  7. 软件——Ubuntu16.04设置静态ip地址

    1.获取网卡名称 在命令行输入ifconfig -a 2.修改网卡配置文件 sudo vim /etc/network/interfaces 加上下面的配置,IP地址可以成适合你的 auto eth0 ...

  8. search(12)- elastic4s-聚合=桶+度量

    这篇我们介绍一下ES的聚合功能(aggregation).聚合是把索引数据可视化处理成可读有用数据的主要工具.聚合由bucket桶和metrics度量两部分组成. 所谓bucket就是SQL的GROU ...

  9. 设计模式之GOF23外观模式

    外观模式 迪米特原则:一个软件实体应当尽可能少的与其他实体发生相互作用 外观模式核心:为子系统提供统一的入口,封装子系统的复杂性,便于客户端调用 相当于找了个代理帮你做了所有事而你只需要和代理打交道

  10. uni-app高分开源电影项目源码案例分析,支持一套代码发布小程序、APP平台多个平台(前端入门必看)

    uni-app-Video 一个优秀的uni-app案例,旨在帮助大家更快的上手uni-app,共同进步! Features ​ 代码编写简洁,注释清晰,快速入门必备: 支持在线模糊搜索: 程序类目懒 ...