码迷,mamicode.com
首页 > 其他好文 > 详细

[hdu5249]动态中位数

时间:2015-06-03 06:07:22      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:

题意: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]动态中位数

标签:

原文地址:http://www.cnblogs.com/jklongint/p/4548175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!