PAT (Advanced Level) Practice 1057 Stack
Posted Keep--Silent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT (Advanced Level) Practice 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 NNN elements, the median value is defined to be the (N/2)(N/2)(N/2)-th smallest element if NNN is even, or ((N+1)/2)((N+1)/2)((N+1)/2)-th if NNN is odd.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer NNN (≤105\\le 10^5≤105). Then NNN 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 10510^5105.
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
大意说明
三种操作:
- 插入x
- 删除x
- 查询中位数
解题思路
数据大小
1
0
5
10^5
105,所以放弃,所以需要一些特定的结构,需要单次插入删除查询三种操作的复杂度必须小于
n
n
n,才能使得总体复杂度不超过
n
2
n^2
n2,所以选择树状数组。
插入与删除
const int Size = 1e5 + 10;
int vt[Size], n = Size - 5;;
int lb(int x) return x & (-x);
void update(int x,int size)
for (int i = x; i <= n; i+=lb(i))
vt[i]+=size;
- 插入x: update(x,1);
- 删除x: update(x,-1);
所以:
- 插入x
- 删除x
- 查询中位数
查询中位数
树状数组表示的是前缀和,我们用vt存储数量 ,二分查找即可: 即我们要查找的是中位数,即查找第一个大于等于一半数量的位置。
int getsum(int index)
int cnt = 0;
for (int i = index; i; i -= lb(i))cnt += vt[i];
return cnt;
void Medeian()
int cnt = getsum(n);
int pot = (cnt+1) / 2;
if (cnt== 0)
printf("Invalid\\n");
return;
int l = 1, r = n;
while (l < r)
int mid = l + r >> 1;
if (getsum(mid) >= pot)r = mid;
else l = mid + 1;
printf("%d\\n",l);
至此
- 插入x
- 删除x
- 查询中位数
复杂度分析
二分复杂度 log n \\log n logn,getsum复杂度 log n \\log n logn,总共 n n n次操作 ,即总体复杂度 n log 2 n n \\log^2 n nlog2n
完整代码
#include <bits/stdc++.h>
using namespace std;
const int Size = 1e5 + 10;
int vt[Size], n = Size - 5;;
int lb(int x) return x & (-x);
void update(int x,int size)
for (int i = x; i <= n; i+=lb(i))
vt[i]+=size;
int getsum(int index)
int cnt = 0;
for (int i = index; i; i -= lb(i))cnt += vt[i];
return cnt;
void Medeian()
int cnt = getsum(n);
int pot = (cnt+1) / 2;
if (cnt== 0)
printf("Invalid\\n");
return;
int l = 1, r = n;
while (l < r)
int mid = l + r >> 1;
if (getsum(mid) >= pot)r = mid;
else l = mid + 1;
printf("%d\\n",l);
int main()
stack<int>sk;
int n,x;
cin >> n;
char ss[300];
while (n--)
scanf("%s", &ss);
if (ss[1] == 'o')
if (sk.size() == 0)
printf("Invalid\\n");
continue;
x = sk.top();
update(x, -1);
sk.pop();
printf("%d\\n", x);
else if (ss[1] == 'u')
scanf("%d", &x);
sk.push(x);
update(x, 1);
else
Medeian();
return 0;
以上是关于PAT (Advanced Level) Practice 1057 Stack的主要内容,如果未能解决你的问题,请参考以下文章