题目大意

要求维护一个栈,提供压栈、弹栈以及求栈内中位数的操作(当栈内元素\(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. python3 之 内置函数enumerate

    python3 内置函数enumerate一.简介: 该函数在字面上是枚举.列举的意思,用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列, 同时列出数据和数据下标,一般用在 for ...

  2. wordpress小程序安装教程

    推荐服务器特价优惠注册即可购买,1G双核一年只要88,真的是白菜价格,点击下面图片即可进入购买地址. 开源小程序发布一段时间了,很多人最近咨询了关于小程序的教程,实在太忙了,抽空写个基本的安装教程. ...

  3. Navicat Premium 12连接ubuntu18 ,Mysql 5.7.27-0

    1,搭建好mysql服务器,cd  /etc/mysql/mysql.conf.d,进入mysql配置目录,vim mysqld.cnf 2,注释掉,bind-address =127.0.0.1 , ...

  4. ubuntu 交叉编译 busybox 1.31.1

    目的:静态编译 Busybox_arm64 1.13.1 环境:Ubuntu 18.04.3 #----------------环境配置 # aarch64-linux-gnu-g++ sudo ap ...

  5. Android ListView的header footer设置visibility gone不起作用

    常用的ViewGroup,例如LinearLayout,在onMeasure方法内对每个child view执行measure前,会判断child view的visibility是否为gone.如果是 ...

  6. .net基础概念

    .net基础概念 1.       .NET Framework 是支持生成和运行下一代应用程序和 XML Web services 的内部 Windows 组件..NET Framework 具有两 ...

  7. MySQL多索引查询选择

    MySQL多索引查询选择 MySQL选择索引-引入 我们知道我们一个表里面可以有多个索引的,那么我们查询数据的时候不指定索引,MySQL就会帮我们自动选择.既然是MySQL程序帮我们自动选择的那么会不 ...

  8. CA-RNN论文读取

    ***CA-RNN: Using Context-Aligned Recurrent Neural Networks for Modeling Sentence Similarity(CA-RNN:使 ...

  9. js表达式和语句趣味题讲解与技术分享

    技术分享 问题1 { a: 1 } + 1 // ? ({ a: 1 }) + 1 // ? 1 + { a: 1 } // ? 答案 { a: 1 } + 1 // 1 ({ a: 1 }) + 1 ...

  10. js杂项积累

    主要内容: 一 浏览器重定向Http请求跨域 二 html select标签 可以设置属性multipe,变为多选 三 document.wirte只应在script标签的顶层代码中使用.不能放在函数 ...