题目大意

要求维护一个栈,提供压栈、弹栈以及求栈内中位数的操作(当栈内元素\(n\)为偶数时,只是求第\(n/2\)个元素而非中间两数的平均值)。最多操作100000次,压栈的数字\(key\)范围是[1,100000]。

题目分析

前两个操作用\(stack\)就好。

求中位数。暴力做法即使用上优先队列也是稳稳的超时。考虑树状数组。

压栈时,将\(key\)值对应的位置加1。弹栈减1。

求中位数,可以二分求出\(sum[1:p]==(n+1)/2\)最小的\(p\),即为\(ans\)。复杂度\(O(nlog^2n)\)。

问题已被解决,但是还有进一步优化的空间。

考虑倍增(?)。从高到低枚举\(ans-1\)的每一个二进制位,即求最大的\(p\)使得\(sum[1:p]<(n+1)/2\)。我们知道树状数组\(tree[k]=\sum_{i=k-lowbit(k)+1}^knum[i]\),也就是说如果我们知道\(\sum_{i=1}^knum[i]=A\)且\((1<<j)<lowbit(k)\),那么\(\sum_{i=1}^{k+(1<<j)}=A+tree[k+(1<<j)]\)。倍增的时候枚举二进制位的时候,恰巧我们也是从大到小枚举的,满足\(j\)与\(k\)的限制。这样,就将一次树状数组上\(logn\)的查询替换成一次简单的加法。复杂度\(O(nlogn)\)。

#include <bits/stdc++.h>

using namespace std;

int num;

stack<int> st;

int sum[100005];

int lowbit(int x) {return x & -x;}

void add(int p, int v) {for (int i = p; i <= 100000; i += lowbit(i)) sum[i] += v;}

/*
int get(int p) {
    int ret = 0;
    for (int i = p; i >= 1; i -= lowbit(i)) ret += sum[i];
    return ret;
}
*/

int main() {
    num = 0;
    while (!st.empty()) st.pop();
    memset(sum, 0, sizeof(sum));

    int n;
    scanf("%d", &n);
    for (int _ = 0; _ < n; ++_) {
        char com[20];
        scanf("%s", com);
        if (strcmp(com, "Push") == 0) {
            int key;
            scanf("%d", &key);
            ++num;
            st.push(key);
            add(key, 1);
        } else if (strcmp(com, "Pop") == 0) {
            if (!st.empty()) {
                int key = st.top();
                printf("%d\n", key);
                --num;
                st.pop();
                add(key, -1);
            } else printf("Invalid\n");
        } else {
            if (!st.empty()) {
                int temp = 0, ans = 0;
                for (int i = 16; i >= 0; --i) {
                    if (ans + (1 << i) > 100000) continue;
                    if (temp + sum[ans + (1 << i)] < (num + 1) / 2) temp += sum[ans += (1 << i)];
                }
                printf("%d\n", ans + 1);
            } else printf("Invalid\n");
        }
    }
    return 0;
}

PAT1057 Stack(树状数组+倍增)的更多相关文章

  1. 【bzoj2819】Nim DFS序+树状数组+倍增LCA

    题目描述 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可以不取.谁不能取谁输.这个游戏是有必胜策略 ...

  2. 1057 Stack 树状数组

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

  3. Luogu P4901 排队 fib数列+树状数组+倍增

    这题让我升华..还好只重构了一遍 首先我们发现:$n$较小时,整个队伍的形态 跟 $n$ 比较大时的局部是一样的 所以我们预处理出这个队伍的形态,和每一行每个位置的质因子个数的前缀和,$O(nlogn ...

  4. CF786C-Till I Collapse【树状数组倍增,优先队列】

    正题 题目链接:https://www.luogu.com.cn/problem/CF786C 题目大意 给出一个长度为\(n\)的序列. 对于每个\(k\in[1,n]\)求将\(n\)分成最少的段 ...

  5. 【BZOJ2819】Nim 树状数组+LCA

    [BZOJ2819]Nim Description 著名游戏设计师vfleaking,最近迷上了Nim.普通的Nim游戏为:两个人进行游戏,N堆石子,每回合可以取其中某一堆的任意多个,可以取完,但不可 ...

  6. PAT-1057 Stack (树状数组 + 二分查找)

    1057. Stack Stack is one of the most fundamental data structures, which is based on the principle of ...

  7. BZOJ 2819: Nim dfs序维护树状数组,倍增

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...

  8. 1057. Stack (30) - 树状数组

    题目如下: Stack is one of the most fundamental data structures, which is based on the principle of Last ...

  9. PAT甲级1057 Stack【树状数组】【二分】

    题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805417945710592 题意:对一个栈进行push, pop和 ...

随机推荐

  1. 机器学习 TensorFlow 实现智能鉴黄

    前言 最近在做一款图床服务,关注公号的小伙伴一定记得小柒曾说过,会在周末放出的,不好意思放大家鸽子了.之所以一直没敢放出,是因为鉴黄接口一直没调试好,虽然我对公号的小伙伴百分之百信任,奈何互联网鱼龙混 ...

  2. 20191121-7 Scrum立会报告+燃尽图 03

    此作业的要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/10067一.小组情况 队名:扛把子 组长:孙晓宇 组员:宋晓丽 梁梦瑶 韩 ...

  3. Linux虚拟机扩容根分区CentOs6.9 VMware14

    1.首先关闭虚拟机点击编辑虚拟机设置 2.点击想要扩容的硬盘点击扩容 3.增加容量 输入想增加的容量,因为我本身是30G写到35G是加了5G不是增加30G.(此处为了演示只增加5G) 4.开启虚拟机 ...

  4. 【论文阅读】Between-class Learning for Image Classification

    文章:Between-class Learning for Image Classification 链接:https://arxiv.org/pdf/1711.10284.pdf CVPR2018 ...

  5. 实现自定义的参数解析器——HandlerMethodArgumentResolver

    1.为什么需要自己实现参数解析器 我们都知道在有注解的接口方法中加上@RequestBody等注解,springMVC会自动的将消息体等地方的里面参数解析映射到请求的方法参数中. 如果我们想要的信息不 ...

  6. word2vec:CBOW和skip-gram模型

    1.CBOW模型 之前已经解释过,无论是CBOW模型还是skip-gram模型,都是以Huffman树作为基础的.值得注意的是,Huffman树中非叶节点存储的中间向量的初始化值是零向量,而叶节点对应 ...

  7. 使用最新AndroidStudio编写Android编程权威指南(第3版)中的代码会遇到的一些问题

    Android编程权威指南(第3版)这本书是基于Android7.0的,到如今已经过于古老,最新的Android版本已经到10,而这本书的第四版目前还没有正式发售,在最近阅读这本书时,我发现这本书的部 ...

  8. HttpClient POST/SET方法

    前言: 网络API接口:https://api.apiopen.top/searchMusic 此API接口返回类型为JSON格式类型 GET:从指定资源请求数据 POST:向指定资源提交要被处理的数 ...

  9. 关于C语言中i++和++i的区别以及printf输出的一些问题。

    a_pos = a++; //后缀,使用a的值之后,递增a b_pre = ++b; //前缀,使用b的值之前,递增b a--和--b同理,不必赘述.这是几乎每个学习过C语言的同学都会知道的,而我在帮 ...

  10. 第三章 学习Shader所需的数学基础(5)

    1. Unity Shader的内置变量(数学篇) 使用Unity写shader的一个好处在于,它提供了很多内置参数,这使得我们不在需要自己手动算一些值.本文给出Unity内置的用于空间变换和摄像机以 ...