L3-002. 堆栈

Posted 给杰瑞一块奶酪~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了L3-002. 堆栈相关的知识,希望对你有一定的参考价值。

大家都知道“堆栈”是一种“先进后出”的线性结构,基本操作有“入栈”(将新元素插入栈顶)和“出栈”(将栈顶元素的值返回并从堆栈中将其删除)。现请你实现一种特殊的堆栈,它多了一种操作叫“查中值”,即返回堆栈中所有元素的中值。对于N个元素,若N是偶数,则中值定义为第N/2个最小元;若N是奇数,则中值定义为第(N+1)/2个最小元。

输入格式:

输入第一行给出正整数N(<= 105)。随后N行,每行给出一个操作指令,为下列3种指令之一:

Push key
Pop
PeekMedian

其中Push表示入栈,key是不超过105的正整数;Pop表示出栈;PeekMedian表示查中值。

输出格式:

对每个入栈指令,将key入栈,并不输出任何信息。对每个出栈或查中值的指令,在一行中打印相应的返回结果。若指令非法,就打印“Invalid”。

输入样例:
17
Pop
PeekMedian
Push 3
PeekMedian
Push 2
PeekMedian
Push 1
PeekMedian
Pop
Pop
Push 5
Push 4
PeekMedian
Pop
Pop
Pop
Pop
输出样例:
Invalid
Invalid
3
2
2
1
2
4
4
5
3
Invalid


Pop和Push都好操作,可以用个数组维持一个栈,关键是求第k小的值(k = n / 2 || k = (n + 1)/ 2),栈的元素个数是变化的,线段树不太会用,所以用树状数组来记录,查找的时候用二分法查找。
代码:
#include <bits/stdc++.h>
using namespace std;
int t[100005],m;
int lowbit(int t)
{
    return t&-t;
}
void update(int x,int y)
{
    for(;x <= 100000;x += lowbit(x))
    {
        t[x] += y;
    }
}
int getsum(int x)
{
    int sum = 0;
    for(;x > 0;x -= lowbit(x))
    {
        sum += t[x];
    }
    return sum;
}
int query(int x)
{
    int l = 1,r = m,mid,sum;
    while(l < r)///相当于桶排序标记每个数出现的次数如果从1到mid一共不到x个数,就让l = mid + 1,但是如果大于或等于x都有可能,所以此时选最左边的值(即query(t)<x && query(t + 1)>=x 选t + 1),所以r = mid 不能让r = mid - 1,不然取的可能不是upper的值
    {
        mid = (l + r) / 2;
        sum = getsum(mid);
        if(sum >= x)r = mid;
        else l = mid + 1;
    }
    //l == r
    return l;
}
int main()
{
    char s[10];
    int n,st[100000],c = 0;
    scanf("%d",&n);
    for(int i = 0;i < n;i ++)
    {
        scanf("%s",s);
        if(s[1] == u)
        {
            scanf("%d",&st[c]);
            if(st[c] > m)m = st[c];
            update(st[c ++],1);
        }
        else if(!c)
        {
            puts("Invalid");
        }
        else
        {
            if(s[1] == o)
            {
                printf("%d\n",st[-- c]);
                update(st[c],-1);
            }
            else
            {
                if(c % 2)printf("%d\n",query((c + 1) / 2));
                else printf("%d\n",query(c / 2));
            }
        }
    }
}

 

以上是关于L3-002. 堆栈的主要内容,如果未能解决你的问题,请参考以下文章

树状数组+二分答案查询第k大的数 (团体程序设计天梯赛 L3-002. 堆栈)

PTA团体程序设计天梯赛-练习集 L3题目总结(不全)

替换或删除后台堆栈上现有片段的代码不起作用

代码适用于与单个 html 文件不同的堆栈片段

在后台堆栈中多次防止相同的片段

从后台堆栈恢复片段时的 savedInstanceState