This documentation is automatically generated by online-judge-tools/verification-helper
#include "data_structure/persistent_stack.cpp"
#include "data_structure/stream.cpp"
#include <cassert>
#include <utility>
template <class T> class realtime_queue {
using Self = realtime_queue<T>;
using stream_type = stream<T>;
using cell_type = typename stream_type::cell_type;
using stack_type = persistent_stack<T>;
public:
using value_type = T;
private:
static stream_type rotate(stream_type f, stack_type b, stream_type t) {
return stream_type([f, b, t]() {
if (f.empty())
return cell_type(std::in_place, b.top(), t);
else
return cell_type(std::in_place, f.top(),
rotate(f.pop(), b.pop(), t.push(b.top())));
});
}
static Self make_queue(stream_type f, stack_type b, stream_type s) {
if (not s.empty())
return Self(f, b, s.pop());
stream_type temp = rotate(f, b, stream_type());
return Self(temp, stack_type(), temp);
}
stream_type front_;
stack_type back_;
stream_type schedule;
realtime_queue(stream_type f, stack_type b, stream_type s)
: front_(f), back_(b), schedule(s) {}
public:
realtime_queue() = default;
bool empty() const { return front_.empty(); }
T front() const {
assert(not empty());
return front_.top();
}
Self push(T x) const { return make_queue(front_, back_.push(x), schedule); }
Self pop() const {
assert(not empty());
return make_queue(front_.pop(), back_, schedule);
}
};
/**
* @brief Realtime Queue
* @see https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
*/
#line 1 "data_structure/persistent_stack.cpp"
#include <cassert>
#include <memory>
#include <utility>
template <class T> class persistent_stack {
using Self = persistent_stack<T>;
class node_type;
using node_ptr = std::shared_ptr<const node_type>;
class node_type {
public:
T value;
node_ptr next;
node_type(T value, node_ptr next) : value(value), next(next) {}
};
node_ptr root;
persistent_stack(node_ptr root) : root(root) {}
public:
persistent_stack() = default;
bool empty() const { return not root; }
T top() const {
assert(not empty());
return root->value;
}
Self push(T x) const {
return Self(std::make_shared<const node_type>(x, root));
}
Self pop() const {
assert(not empty());
return Self(root->next);
}
Self reverse() const {
Self ret;
Self x = *this;
while (not x.empty()) {
ret = ret.push(x.top());
x = x.pop();
}
return ret;
}
};
/**
* @brief Persistent Stack
*/
#line 1 "other/suspension.cpp"
#include <functional>
#line 4 "other/suspension.cpp"
#include <variant>
template <class T>
class suspension
: private std::shared_ptr<std::variant<T, std::function<T()>>> {
public:
using value_type = T;
using func_type = std::function<T()>;
using node_type = std::variant<T, func_type>;
private:
using base_type = std::shared_ptr<node_type>;
static T get(node_type &x) {
if (x.index() != 0)
x = std::get<1>(x)();
return std::get<0>(x);
}
template <class... Args> static base_type make_node(Args &&... args) {
return std::make_shared<node_type>(std::forward<Args>(args)...);
}
public:
suspension(std::in_place_t, T x)
: base_type(make_node(std::in_place_index<0>, x)) {}
suspension(func_type f) : base_type(make_node(std::in_place_index<1>, f)) {}
T force() const { return get(**this); }
};
/**
* @brief Suspension
* @see https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
*/
#line 2 "data_structure/stream.cpp"
#line 4 "data_structure/stream.cpp"
#include <optional>
#line 6 "data_structure/stream.cpp"
template <class T>
class stream : private suspension<std::optional<std::pair<T, stream<T>>>> {
using Self = stream<T>;
public:
using value_type = T;
using cell_type = std::optional<std::pair<T, Self>>;
private:
using base_type = suspension<cell_type>;
stream(T x, Self s)
: base_type(std::in_place, cell_type(std::in_place, x, s)) {}
public:
stream() : base_type(std::in_place, cell_type(std::nullopt)) {}
stream(std::function<cell_type()> f) : base_type(f) {}
using base_type::force;
bool empty() const { return not force().has_value(); }
T top() const {
assert(not empty());
return (*force()).first;
}
Self push(T x) const { return Self(x, *this); }
Self pop() const {
assert(not empty());
return (*force()).second;
}
Self reverse() const {
return Self([x = *this]() mutable {
Self ret;
while (not x.empty()) {
ret = ret.push(x.top());
x = x.pop();
}
return ret.force();
});
}
friend Self operator+(Self l, Self r) {
return Self([l, r]() {
if (l.empty())
return r.force();
else
return cell_type(std::in_place, l.top(), l.pop() + r);
});
}
};
/**
* @brief Stream
* @see https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
*/
#line 3 "data_structure/realtime_queue.cpp"
#line 6 "data_structure/realtime_queue.cpp"
template <class T> class realtime_queue {
using Self = realtime_queue<T>;
using stream_type = stream<T>;
using cell_type = typename stream_type::cell_type;
using stack_type = persistent_stack<T>;
public:
using value_type = T;
private:
static stream_type rotate(stream_type f, stack_type b, stream_type t) {
return stream_type([f, b, t]() {
if (f.empty())
return cell_type(std::in_place, b.top(), t);
else
return cell_type(std::in_place, f.top(),
rotate(f.pop(), b.pop(), t.push(b.top())));
});
}
static Self make_queue(stream_type f, stack_type b, stream_type s) {
if (not s.empty())
return Self(f, b, s.pop());
stream_type temp = rotate(f, b, stream_type());
return Self(temp, stack_type(), temp);
}
stream_type front_;
stack_type back_;
stream_type schedule;
realtime_queue(stream_type f, stack_type b, stream_type s)
: front_(f), back_(b), schedule(s) {}
public:
realtime_queue() = default;
bool empty() const { return front_.empty(); }
T front() const {
assert(not empty());
return front_.top();
}
Self push(T x) const { return make_queue(front_, back_.push(x), schedule); }
Self pop() const {
assert(not empty());
return make_queue(front_.pop(), back_, schedule);
}
};
/**
* @brief Realtime Queue
* @see https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf
*/