Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iomanip>
- #include <iostream>
- #include <vector>
- class ImplicitTreap {
- public:
- ImplicitTreap();
- ~ImplicitTreap();
- void insert(size_t position, const int& value);
- void remove(size_t position);
- void clear();
- int get(size_t position) const;
- private:
- struct Node {
- Node(const int& value);
- // Fixes treeSize
- void fix();
- // Stores size of subtree
- size_t treeSize;
- // Priority of current node
- int priority;
- // Value to store
- int value;
- // Pointers tp left and right children
- Node* left;
- Node* right;
- };
- private:
- std::pair<Node*, Node*> split(Node* node, size_t position);
- Node* merge(Node* node1, Node* node2);
- void clear(Node* node);
- private:
- Node* _root;
- };
- ImplicitTreap::ImplicitTreap() : _root(nullptr) {}
- ImplicitTreap::~ImplicitTreap() { clear(); }
- void ImplicitTreap::clear() {
- clear(_root);
- _root = nullptr;
- }
- void ImplicitTreap::clear(Node* node) {
- if (node == nullptr) return;
- clear(node->left);
- clear(node->right);
- delete node;
- }
- void ImplicitTreap::insert(size_t position, const int& value) {
- Node* current = new Node(value);
- std::pair<Node*, Node*> ans = split(_root, position);
- Node* right = merge(current, ans.second);
- _root = merge(ans.first, right);
- }
- void ImplicitTreap::remove(size_t position) {
- std::pair<Node*, Node*> ans1 = split(_root, position);
- std::pair<Node*, Node*> ans2 = split(ans1.second, 1);
- delete ans2.first;
- _root = merge(ans1.first, ans2.second);
- }
- int ImplicitTreap::get(size_t position) const {
- size_t l;
- Node* node = _root;
- do {
- l = (node->left != nullptr) ? (node->left->treeSize) : 0;
- if (l == position) break;
- if (position < l) {
- node = node->left;
- } else {
- position -= l + 1;
- node = node->right;
- }
- } while (true);
- return node->value;
- }
- std::pair<ImplicitTreap::Node*, ImplicitTreap::Node*> ImplicitTreap::split(
- Node* node, size_t position) {
- if (node == nullptr) return std::pair<Node*, Node*>(nullptr, nullptr);
- size_t l = (node->left != nullptr) ? (node->left->treeSize) : 0;
- if (l >= position) {
- std::pair<Node*, Node*> ans = split(node->left, position);
- node->left = ans.second;
- node->fix();
- return std::make_pair(ans.first, node);
- } else {
- std::pair<Node*, Node*> ans = split(node->right, position - l - 1);
- node->right = ans.first;
- node->fix();
- return std::make_pair(node, ans.second);
- }
- }
- ImplicitTreap::Node* ImplicitTreap::merge(Node* node1, Node* node2) {
- if (node2 == nullptr) return node1;
- if (node1 == nullptr) return node2;
- if (node1->priority > node2->priority) {
- node1->right = merge(node1->right, node2);
- node1->fix();
- return node1;
- } else {
- node2->left = merge(node1, node2->left);
- node2->fix();
- return node2;
- }
- }
- ImplicitTreap::Node::Node(const int& value)
- : value(value),
- priority(rand()),
- left(nullptr),
- right(nullptr),
- treeSize(1) {}
- void ImplicitTreap::Node::fix() {
- treeSize = 1;
- if (left != nullptr) treeSize += left->treeSize;
- if (right != nullptr) treeSize += right->treeSize;
- }
- int alpha = 0;
- std::vector<int> Code(const std::vector<int>& v) {
- ImplicitTreap permutation;
- for (int i = 0; i < alpha; ++i) {
- permutation.insert(i, i + 1);
- }
- std::vector<int> res;
- int in = 0;
- int out = 0;
- for (int i = 0; i < v.size(); ++i) {
- in = v[i];
- out = permutation.get(in - 1);
- res.push_back(out);
- permutation.remove(out - 1);
- permutation.insert(0, in);
- }
- return res;
- }
- std::vector<int> Decode(const std::vector<int>& v) {
- ImplicitTreap permutation;
- for (int i = 0; i < alpha; ++i) {
- permutation.insert(i, i + 1);
- }
- std::vector<int> res;
- int in = 0;
- int out = 0;
- for (int i = 0; i < v.size(); ++i) {
- in = v[i];
- int mid = in;
- bool flag = false;
- while ((mid = permutation.get(mid - 1)) != in) {
- out = mid;
- flag = true;
- } if (!flag) {
- out = permutation.get(in - 1);
- }
- res.push_back(out);
- permutation.remove(in - 1);
- permutation.insert(0, out);
- }
- return res;
- }
- /*
- int main() {
- //std::srand(std::time(nullptr));
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(NULL);
- int len = 0;
- std::cin >> len >> alpha;
- std::vector<int> start;
- for (int i = 0; i < len; ++i) {
- start.push_back(1 + std::rand() % alpha);
- }
- auto code = Code(start);
- auto res = Decode(code);
- if (res != start) {
- std::cout << "START: ";
- for (int i = 0; i < start.size(); ++i) {
- std::cout << start[i] << ' ';
- }
- std::cout << '\n';
- std::cout << "CODER: ";
- for (int i = 0; i < code.size(); ++i) {
- std::cout << code[i] << ' ';
- }
- std::cout << '\n';
- std::cout << "RESUL: ";
- for (int i = 0; i < res.size(); ++i) {
- std::cout << res[i] << ' ';
- }
- std::cout << '\n';
- }
- }
- */
- int main() {
- std::ios_base::sync_with_stdio(false);
- std::cin.tie(NULL);
- int len, alpha, type = 0;
- std::cin >> len >> alpha >> type;
- ImplicitTreap permutation;
- for (int i = 0; i < alpha; ++i) {
- permutation.insert(i, i + 1);
- }
- if (type == 2) {
- int in = 0;
- int out = 0;
- for (int i = 0; i < len; ++i) {
- std::cin >> in;
- out = permutation.get(in - 1);
- std::cout << out << ' ';
- permutation.remove(in - 1);
- permutation.insert(0, out);
- }
- } else {
- int in = 0;
- int out = 0;
- for (int i = 0; i < len; ++i) {
- std::cin >> in;
- out = permutation.get(in - 1);
- std::cout << out << ' ';
- permutation.remove(out - 1);
- permutation.insert(0, in);
- }
- }
- return 0;
- }
- /*
- * START: 2 2 3 3 2 3 1
- * CODER: 2 1 3 1 2 1 3
- * RESUL: 2 2 3 3 2 2 1
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement