-
Notifications
You must be signed in to change notification settings - Fork 16
/
min_queue.cpp
153 lines (129 loc) · 3.09 KB
/
min_queue.cpp
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
141
142
143
144
145
146
147
148
149
150
151
152
153
// use std::greater to make max_queue
// to use min_stack2, set needed array size in min_stack2 and change
// [min_stack s1, s2;] to [min_stack2 s1, s2;]
template<typename T, typename Comp = std::less<T>>
struct min_queue {
struct min_stack {
vector<pair<T, T>> v;
void push(const T &x) {
if (v.empty()) {
v.eb(x, x);
return;
}
const T &was = v.back().first;
v.eb((Comp()(x, was) ? x : was), x);
}
void pop() {
v.pop_back();
}
T extract() {
auto res = v.back().second;
v.pop_back();
return res;
}
T get_min() const {
return v.back().first;
}
T top() const {
return v.back().second;
}
bool empty() const {
return v.empty();
}
int size() const {
return v.size();
}
void clear() {
v.clear();
}
};
struct min_stack2 {
array<pair<T, T>, 12345> v;
int iv = 0;
void push(const T &x) {
if (iv == 0) {
v[iv++] = make_pair(x, x);
return;
}
const T &was = v[iv - 1].first;
v[iv++] = make_pair((Comp()(x, was) ? x : was), x);
}
void pop() {
--iv;
}
T extract() {
auto res = v[iv - 1].second;
--iv;
return res;
}
T get_min() const {
return v[iv - 1].first;
}
T top() const {
return v[iv - 1].second;
}
bool empty() const {
return iv == 0;
}
int size() const {
return iv;
}
void clear() {
iv = 0;
}
};
min_stack s1, s2;
void push(const T &x) {
s2.push(x);
}
void pop() {
if (s1.empty()) {
while (!s2.empty())
s1.push(s2.extract());
}
s1.pop();
}
T front() {
if (s1.empty()) {
while (!s2.empty())
s1.push(s2.extract());
}
return s1.top();
}
T get_min() const {
if (s1.empty()) return s2.get_min();
else if (s2.empty()) return s1.get_min();
T a = s1.get_min();
T b = s2.get_min();
return (Comp()(a, b) ? a : b);
}
bool empty() const {
return s1.empty() && s2.empty();
}
int size() const {
return s1.size() + s2.size();
}
void clear() {
s1.clear();
s2.clear();
}
};
template<typename T, typename U>
ostream &operator << (ostream &o, const min_queue<T, U> &q) {
o << "[";
bool first = true;
for (int i = (int)q.s1.size() - 1; i >= 0; --i) {
if (!first)
o << ", ";
o << q.s1.v[i].second;
first = false;
}
o << " | ";
for (int i = 0; i < q.s2.size(); ++i) {
if (!first)
o << ", ";
o << q.s2.v[i].second;
first = false;
}
return o;
}