1057. Stack (30) - 树状数组
题目如下:
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
这个题目我最初用的是string、stringstream和vector来做,发现会严重超时,后来在网上参考了和山米兰的解法,发现他的方法很有技巧,分析如下:
①对命令的解析,只看第二位,如果是o,说明是Pop,如果是e,说明是PeekMedian,否则是push,是push则应当再读入一次数字,这比用getline要好的多,因为getline还需要排除第一个输入的N。
②求中位数的思想,不是排序找中间的值,而是通过统计从1开始的每个元素的个数放到数组C中,这样从前到后,数组C的子列和为题目要求的位置时,拿到的就是中位数。
③求子列和的思想,因为是从前到后的前缀和,可以利用树状数组,下面的代码利用add实现了添加和删除两种操作,利用value的不同,1表示添加,2表示删除。树状数组的基本思想就是数组C中不同元素管辖不同的区域,如果要添加一个元素,则所有满足区域条件的位置都要+value,反之如果删除,所有满足条件的区域都要-value。本题要求的是统计1~100000的元素个数,因此value=+1或者-1。
④求子列和为题目要求的值,利用二分查找。
- #include<stdio.h>
- #include<cstring>
- #include<iostream>
- #include<string>
- using namespace std;
- const int N=100001;
- int c[N];
- int lowbit(int i){
- return i&(-i);
- }
- void add(int pos,int value){
- while(pos<N){
- c[pos]+=value;
- pos+=lowbit(pos);
- }
- }
- int sum(int pos){
- int res=0;
- while(pos>0){
- res+=c[pos];
- pos-=lowbit(pos);
- }
- return res;
- }
- int find(int value){
- int l=0,r=N-1,median,res;
- while(l<r-1){
- if((l+r)%2==0)
- median=(l+r)/2;
- else
- median=(l+r-1)/2;
- res=sum(median);
- if(res<value)
- l = median;
- else
- r = median;
- }
- return l+1;
- }
- int main(){
- char ss[20];
- int stack[N],top=0,n,pos;
- memset(c,0,sizeof(c));
- scanf("%d",&n);
- while(n--){
- scanf("%s",ss);
- if(ss[1]=='u'){
- scanf("%d",&pos);
- stack[++top]=pos;
- add(pos,1);
- }else if(ss[1]=='o'){
- if(top==0){
- printf("Invalid\n");
- continue;
- }
- int out=stack[top];
- add(out,-1); // 删除元素out
- printf("%d\n",stack[top--]);
- }else if(ss[1]=='e'){
- if(top==0){
- printf("Invalid\n");
- continue;
- }
- int res;
- if(top%2==0)
- res=find(top/2);
- else
- res=find((top+1)/2);
- printf("%d\n",res);
- }else{
- printf("Invalid\n");
- }
- }
- return 0;
- }
1057. Stack (30) - 树状数组的更多相关文章
- PAT甲级题解-1057. Stack (30)-树状数组
不懂树状数组的童鞋,正好可以通过这道题学习一下树状数组~~百度有很多教程的,我就不赘述了 题意:有三种操作,分别是1.Push key:将key压入stack2.Pop:将栈顶元素取出栈3.PeekM ...
- pat 甲级 1057 Stack(30) (树状数组+二分)
1057 Stack (30 分) Stack is one of the most fundamental data structures, which is based on the princi ...
- PAT 1057 Stack [难][树状数组]
1057 Stack (30)(30 分) Stack is one of the most fundamental data structures, which is based on the pr ...
- PAT甲级1057 Stack【树状数组】【二分】
题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592 题意:对一个栈进行push, pop和 ...
- PAT-1057 Stack (树状数组 + 二分查找)
1057. Stack Stack is one of the most fundamental data structures, which is based on the principle of ...
- PAT1057 Stack(树状数组+倍增)
目录 题目大意 题目分析 题目大意 要求维护一个栈,提供压栈.弹栈以及求栈内中位数的操作(当栈内元素\(n\)为偶数时,只是求第\(n/2\)个元素而非中间两数的平均值).最多操作100000次,压栈 ...
- POJ1990--POJ 1990 MooFest(树状数组)
Time Limit: 1000MSMemory Limit: 30000K Total Submissions: 8141Accepted: 3674 Description Every year, ...
- PAT 甲级1057 Stack (30 分)(不会,树状数组+二分)*****
1057 Stack (30 分) Stack is one of the most fundamental data structures, which is based on the prin ...
- 1057 Stack (30分)(树状数组+二分)
Stack is one of the most fundamental data structures, which is based on the principle of Last In Fir ...
随机推荐
- VMWare 学习目录
Linux介绍 Linux入门--个人感想 Google怎么用linux 初入Linux Windows XP硬盘安装Ubuntu 12.04双系统图文详解 实例讲解虚拟机3种网络模式(桥接.nat. ...
- Java内存模型之重排序
参考链接:https://blog.csdn.net/huzhigenlaohu/article/details/51595676
- 关于一些基础的Java问题的解答(四)
16. Java面向对象的三个特征与含义 java中的面向对象的三大基本特征分别是:封装.继承.多态: 封装:把过程和数据包围起来,对数据的访问只能通过已定义的界面,主要是方便类的修改 继承:对象的一 ...
- 利用Apach ab对nodejs进行并发负载的压力测试
大家应该都有听过,nodejs性能优越,并发也很好之类的话,那我们用Apache ab对node这个空框架测试一下,然后再对一些网站测试一下,或或少一定的参考意义把. Apache ab测试工具是模拟 ...
- Python小代码_4_省市区三级菜单
menu = { "北京": { "朝阳区": { "三环到四环之间": {}, "四环到五环之间": {}, &quo ...
- 数据库4m10d作业
Create table student ( Sno char(15) primary key , Sname varchar(10) not null, Sage tinyint , Special ...
- ABP文档笔记 - 数据过滤
预定义的过滤 ISoftDelete 软删除过滤用来在查询数据库时,自动过滤(从结果中抽取)已删除的实体.如果一个实体可以被软删除,它必须实现ISoftDelete接口,该接口只定义了一个IsDele ...
- MySQL EXTRACT() 函数
定义和用法 EXTRACT() 函数用于返回日期/时间的单独部分,比如年.月.日.小时.分钟等等. 语法 EXTRACT(unit FROM date) date 参数是合法的日期表达式.unit 参 ...
- 守护态运行Docker容器
更多的时候,需要让 Docker 容器在后台以守护态(Daemonized)形式运行.此时,可以通过添加 -d 参数来实现. 例如下面的命令会在后台运行容器. $ sudo docker run -d ...
- 硬盘存储计量单位KB、MB、GB大小换算
一. 预备知识 1. bit与byte 1. bit(简记为 b) 1 bit = 0 or 1 = one binary 2. byte(简记为 B) 1 byte = 8 bits 1字节,8个二 ...