题意:3种操作分别为入队,出队,查询当前队列的中位数。操作数为1e5数量级。

思路:先考虑离线算法,可以离散+线段树,可以划分树,考虑在线算法,则有treap名次树,SBtree(size balanced tree)等等。

///这个模板有问题,别再用了。。。!!!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <queue>
using namespace std;
const int maxn = 1e5 + 7;
template<typename T> class SBTree {
public:
    SBTree() {
        root = nil = new Node();
        nil->ch[0] = nil->ch[1] = nil;
        nil->sz = 0;
        tot = top = 0;
    }
    ~SBTree() {}
 
    void clear() {
        root = nil; tot = top = 0;
    }
    int size() { return root->sz; }
    bool empty() { return root == nil; }
    void insert(const T &it) { insert(root, it); }
    void erase(const T &it) { erase(root, it); }
    bool find(const T &it) { return find(root, it); }
    const T &minItem() { return minMax(root, 0); }
    const T &maxItem() { return minMax(root, 1); }
    const T &select(int k) { return select(root, k); }
    int rank(const T &it) { return rank(root, it); }
 
private:
    const static int maxn = 1e4 + 7;
    struct Node {
        T key;
        int sz;
        Node *ch[2];
    } v[maxn], *stk[maxn], *root, *nil;
 
    int tot, top;
 
    void rotate(Node *&x, int d) {
        Node *y = x->ch[d ^ 1];
        x->ch[d ^ 1] = y->ch[d]; y->ch[d] = x;
        y->sz = x->sz; x->sz = x->ch[0]->sz + x->ch[1]->sz + 1;
        x = y;
    }
 
    void maintain(Node *&x, int d) {
        if (x == nil) return;
        if (x->ch[d]->sz < x->ch[d ^ 1]->ch[d ^ 1]->sz) rotate(x, d);
        else if (x->ch[d]->sz < x->ch[d ^ 1]->ch[d]->sz) {
            rotate(x->ch[d ^ 1], d ^ 1); rotate(x, d);
        else {
            return;
        }
        maintain(x->ch[0], 1); maintain(x->ch[1], 0);
        maintain(x, 1); maintain(x, 0);
    }
 
    void insert(Node *&x, const T &it) {
        if (x == nil) {
            x = top ? stk[top--] : v + tot++;
            x->key = it; x->sz = 1;
            x->ch[0] = x->ch[1] = nil;
        else {
            ++x->sz;
            insert(x->ch[x->key < it], it);
            maintain(x, it < x->key);
        }
    }
 
    void erase(Node *&x, const T &it) {
        Node *p;
        if (x == nil) return;
        --x->sz;
        if (it < x->key) erase(x->ch[0], it);
        else if (x->key < it) erase(x->ch[1], it);
        else {
            if (x->ch[1] == nil) {
                stk[++top] = x; x = x->ch[0];
            else {
                for (p = x->ch[1]; p->ch[0] != nil; p = p->ch[0]);
                erase(x->ch[1], x->key = p->key);
            }
        }
    }
 
    bool find(const Node *x, const T &it) {
        if (x == nil || !(it < x->key || x->key < it)) return x != nil;
        return find(x->ch[x->key < it], it);
    }
 
    const T &minMax(const Node *x, int d) {
        return x->ch[d] == nil ? x->key : minMax(x->ch[d], d);
    }
 
    const T &select(const Node *x, int k) {
        if (x == nil || k == x->ch[0]->sz + 1) return x->key;
        return select(x->ch[x->ch[0]->sz + 1 < k], x->ch[0]->sz + 1 < k ? k - x->ch[0]->sz - 1 : k);
    }
 
    int rank(const Node *x, const T &it) {
        if (x == nil) return 1;
        if (it < x->key) return rank(x->ch[0], it);
        if (x->key < it) return rank(x->ch[1], it) + x->ch[0]->sz + 1;
        return x->ch[0]->sz + 1;
    }
};
SBTree<int> sbt;
int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt""r", stdin);
#endif // ONLINE_JUDGE
    int cas = 0, n;
    while (cin >> n) {
        printf("Case #%d:\n", ++ cas);
        sbt.clear();
        queue<int> Q;
        while (n --) {
            char s[10];
            scanf("%s", s);
            if (s[0] == 'i') {
                int x;
                scanf("%d", &x);
                sbt.insert(x);
                Q.push(x);
            }
            else if (s[0] == 'o') {
                int x = Q.front();
                Q.pop();
                sbt.erase(x);
            }
            else {
                int sz = Q.size();
                printf("%d\n", sbt.select(sz / 2 + 1));
            }
        }
    }
    return 0;
}

[hdu5249]动态中位数的更多相关文章

  1. AcWing:106. 动态中位数(对顶堆)

    依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数. 输入格式 第一行输入一个整数PP,代表后面数据集的个数,接下来若干行输入各个数据集. 每个数据集的第一行首先 ...

  2. HDU 3282 Running Median 动态中位数,可惜数据范围太小

    Running Median Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pi ...

  3. POJ 3784 Running Median (动态中位数)

    题目链接:http://poj.org/problem?id=3784 题目大意:依次输入n个数,每当输入奇数个数的时候,求出当前序列的中位数(排好序的中位数). 此题可用各种方法求解. 排序二叉树方 ...

  4. hdu5249KPI动态中位数(两个set)

    题意(中问题直接粘题意吧)                                                                      KPI Problem Descr ...

  5. 动态中位数-POJ 3784

    题目: 依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数. 输入格式 第一行输入一个整数P,代表后面数据集的个数,接下来若干行输入各个数据集. 每个数据集的第一 ...

  6. POJ 3784 Running Median【维护动态中位数】

    Description For this problem, you will write a program that reads in a sequence of 32-bit signed int ...

  7. AcWing 106. 动态中位数

    依次读入一个整数序列,每当已经读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数. #include<bits/stdc++.h> using namespace std; pri ...

  8. luogu_1168: 中位数

    洛谷1168:中位数(对顶堆) 题目描述: 给定一个长度为\(N\)的非负整数序列\(A_i\),对于所有\((1\leq k\leq\frac{N+1}{2})\),输出\(A_1,A_3,..., ...

  9. 牛客练习赛63 C 牛牛的揠苗助长 主席树 二分 中位数

    LINK:牛牛的揠苗助长 题目很水 不过做法很多 想到一个近乎O(n)的做法 不过感觉假了 最后决定莽一个主席树 当然 平衡树也行. 容易想到 答案为ans天 那么一些点的有效增长项数为 ans%n. ...

随机推荐

  1. TCP基础概念

    定义 传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的.可靠的.基于字节流的传输层通信协议 特点 TCP是一种面向广域网的通信协议,目的是在跨越多个网 ...

  2. Laravel Passport token过期后判断refresh_token是否过期

    需求:前后端分离状态下,登录失效(token过期)后,前端需要知道下一步是跳转到登录页面还是使用refresh_token刷新token. 这就需要后端根据是否可以刷新token(refresh_to ...

  3. linux CVE-2019-13272 本地特权漏洞

    漏洞描述 在5.1.17之前的Linux内核中,kernel / ptrace.c中的ptrace_link错误地处理了想要创建ptrace关系的进程的凭据记录,这允许本地用户通过利用父子的某些方案来 ...

  4. Linux常见提权

    常见的linux提权 内核漏洞提权 查看发行版 cat /etc/issue cat /etc/*-release 查看内核版本 uname -a 查看已经安装的程序 dpkg -l rpm -qa ...

  5. 如何将dotnet core webapi发布到docker中…

    如何将dotnet core webapi发布到docker中 今天想起来撸一下docker,中途还是遇到些问题,但是这些问题都是由于路径什么的导致不正确,在这儿还是记录下操作过程,今天是基于wind ...

  6. redis: 其他数据类型(八)

    1.geospatial 地理位置 有效的经度从-180度到180度 有效的纬度从-85.05112878度到85.05112878度 当坐标位置超出上述指定范围时,该命令将会返回一个错误 底层实现原 ...

  7. redis: Set集合类型(五)

    Set里面的值是不能重复的 Set设置值(头部):sadd myset hello Set获取值:smembers myset 检查Set是否包含某个元素:sismember myset hello ...

  8. MergeSort归并排序和利用归并排序计算出数组中的逆序对

    首先先上LeetCode今天的每日一题(面试题51. 数组中的逆序对): 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. ...

  9. python 字符与数字如何转换

    python中字符与数字相互转换用chr()即可. python中的字符数字之间的转换函数 int(x [,base ])                               将x转换为一个整 ...

  10. 在c++中引用c头文件里的函数

    在c++中有的时候想要引用c头文件里的函数有两种方法;就拿c语言里面的<stdlib.h>举例 在c中我们想要用<stdlib.h>里的函数,形式为:#include<s ...