题意: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;
}
|