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. java 8 stream reduce详解和误区

    目录 简介 reduce详解 总结 java 8 stream reduce详解和误区 简介 Stream API提供了一些预定义的reduce操作,比如count(), max(), min(), ...

  2. 2.Python是什么?使用Python的好处是什么?

    Python是什么?使用Python的好处是什么? 答: Python is a programming language with objects, modules, threads, except ...

  3. Netty(四):AbstractChannel源码解析

    首先我们通过一张继承关系的图来认识下AbstractChannel在Netty中的位置. 除了Comaprable接口来自java自带的包,其他都是Netty包中提供的. Comparable接口定义 ...

  4. uniq 只能相邻行去重

    uniq只可以将相邻行重复数据进行去重处理: [root@localhost /data/mysql/mysql3306]#last | cut -d ' ' -f 1 | tail -15 > ...

  5. LFS资料和SSH远程登录全过程

    LFS 即 Linux From Scratch, From Scratch的意思是"白手起家",即从0开始安装Linux,它的所有软件包都需要从源代码开始编译安装.这是通过实际动 ...

  6. DFS--POJ 1190 生日蛋糕

    Description 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i(1 <= i <= M)层蛋糕是半径为Ri ...

  7. 题目分享N

    题意:有辆车,有r行,s*2列,在第s列和第s+1列之间有个过道,出口在第r+1行的过道处,现在给出每个人的位置(行号和列号),每人每次只能动一格,问最少耗费多长时间全员才能逃出去 分析:假如车上只有 ...

  8. C. Ilya And The Tree 树形dp 暴力

    C. Ilya And The Tree 写法还是比较容易想到,但是这么暴力的写法不是那么的敢写. 就直接枚举了每一个点上面的点的所有的情况,对于这个点不放进去特判一下,然后排序去重提高效率. 注意d ...

  9. S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的

    S - Making the Grade POJ - 3666 这个题目要求把一个给定的序列变成递增或者递减序列的最小代价. 这个是一个dp,对于这个dp的定义我觉得不是很好想,如果第一次碰到的话. ...

  10. CSS颜色及文本字体

    CSS颜色及文本字体 CSS颜色表示法 CSS文本设置 CSS边框属性 背景属性 元素溢出 CSS颜色及文本字体 CSS颜色表示法 颜色名表示,比如:red 红色,yellow黄色,pick粉色 16 ...