Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <math.h>
- #include <algorithm>
- #include <iostream>
- #include <vector>
- class Treap {
- private:
- struct Node {
- int value = 0;
- int lefts = 0;
- int rights = 0;
- int min = 0;
- int prior = rand() % 1500000;
- int size = 1;
- Node* left = nullptr;
- Node* right = nullptr;
- bool rev = false;
- Node(int val) { value = val; }
- };
- typedef Node* Pnode;
- Pnode root_ = nullptr;
- void Merge(Pnode first, Pnode second);
- void MergeHelper(Pnode& current, Pnode t1, Pnode t2);
- std::pair<Pnode, Pnode> Split(size_t key);
- void SplitHelper(Pnode current, size_t key, Pnode& left, Pnode& right);
- void Update(Pnode node);
- static int Min(int val1, int val2, int val3) {
- std::vector<int> temp = {val1, val2, val3};
- std::sort(temp.begin(), temp.end());
- return temp[0];
- }
- void PrintHelper(Pnode current) {
- if (current == nullptr) {
- return;
- }
- // i++;
- // int temp = i;
- // i++;
- Push(current);
- PrintHelper(current->left);
- std::cout << current->value << " ";
- PrintHelper(current->right);
- // std::cout << current->value << " ";
- }
- Treap(Pnode node) { root_ = node; }
- void ClearHelper(Pnode node) {
- if (node == nullptr) {
- return;
- }
- ClearHelper(node->left);
- ClearHelper(node->right);
- delete node;
- }
- void Push(Pnode node) {
- if (node == nullptr) {
- return;
- }
- if (!node->rev) {
- return;
- }
- if (node != nullptr && node->rev) {
- node->rev = false;
- std::swap(node->left, node->right);
- if (node->left != nullptr) {
- node->left->rev ^= true;
- }
- if (node->right != nullptr) {
- node->right->rev ^= true;
- }
- }
- }
- void ReverseHelper(int left, int right);
- public:
- void Print() {
- // int i = 0;
- PrintHelper(root_);
- std::cout << "\n";
- }
- Treap() { root_ = nullptr; };
- void Insert(size_t pos, int value);
- size_t& Size();
- int GetMin(size_t left, size_t right);
- void Clear();
- void Reverse(int left, int right);
- };
- void Treap::Reverse(int left, int right) { ReverseHelper(left, right); }
- void Treap::ReverseHelper(int left, int right) {
- std::pair<Pnode, Pnode> res = Split(left - 1); // got t1, t2
- Treap temp(res.second); // new tree to split
- std::pair<Pnode, Pnode> res2 = temp.Split(right - left + 1);
- res2.first->rev ^= true;
- temp.Merge(res2.first, res2.second);
- Merge(res.first, temp.root_);
- }
- void Treap::Clear() { ClearHelper(root_); }
- std::pair<Treap::Pnode, Treap::Pnode> Treap::Split(size_t key) {
- Pnode left = nullptr;
- Pnode right = nullptr;
- SplitHelper(root_, key, left, right);
- return {left, right};
- }
- void Treap::SplitHelper(Pnode current, size_t key, Pnode& left, Pnode& right) {
- if (current == nullptr) {
- left = nullptr;
- right = nullptr;
- return;
- }
- Push(current);
- size_t curr_key = (current->left == nullptr ? 0 : current->left->size) + 1;
- if (curr_key <= key) {
- SplitHelper(current->right, key - curr_key, current->right, right);
- left = current;
- } else {
- SplitHelper(current->left, key, left, current->left);
- right = current;
- }
- Update(current);
- }
- void Treap::Update(Pnode node) {
- node->lefts = (node->left != nullptr) ? node->left->size : 0;
- node->rights = (node->right != nullptr) ? node->right->size : 0;
- int min = node->value;
- if (node->left != nullptr && node->right != nullptr) {
- min = Min(node->left->min, node->right->min, node->value);
- } else if (node->left != nullptr) {
- min = std::min(node->left->min, node->value);
- } else if (node->right != nullptr) {
- min = std::min(node->right->min, node->value);
- }
- node->min = min;
- node->size = 1 + node->lefts + node->rights;
- }
- void Treap::MergeHelper(Pnode& current, Pnode t1, Pnode t2) {
- Push(t1);
- Push(t2);
- if (t1 == nullptr || t2 == nullptr) {
- current = t1 ? t1 : t2;
- } else if (t1->prior > t2->prior) {
- MergeHelper(t1->right, t1->right, t2);
- current = t1;
- } else {
- MergeHelper(t2->left, t1, t2->left);
- current = t2;
- }
- Update(current);
- }
- void Treap::Merge(Pnode first, Pnode other) {
- MergeHelper(root_, first, other);
- }
- void Treap::Insert(size_t pos, int value) {
- std::pair<Pnode, Pnode> res = Split(pos);
- Pnode m = new Node(value);
- Treap temp;
- temp.Merge(res.first, m);
- this->Merge(temp.root_, res.second);
- }
- int Treap::GetMin(size_t left, size_t right) {
- int result = 0;
- Treap r_tree;
- Pnode copy_root = root_;
- Treap copy(copy_root);
- std::pair<Pnode, Pnode> res = copy.Split(left - 1);
- r_tree.root_ = res.second;
- // l_tree.root_ = res.first;
- std::pair<Pnode, Pnode> res2 = r_tree.Split(right - left + 1);
- result = res2.first->min;
- r_tree.Merge(res2.first, res2.second);
- Merge(res.first, r_tree.root_);
- return result;
- }
- void Requests() {
- size_t n = 0;
- size_t m = 0;
- std::cin >> n >> m;
- Treap treap;
- // std::vector<int> vect;
- int val = 0;
- for (size_t i = 0; i < n; ++i) {
- std::cin >> val;
- // vect.push_back(val);
- treap.Insert(i, val);
- // treap.Print();
- }
- // treap.Print();
- // std::cout<<"-------\n";
- char request = 0;
- for (size_t i = 0; i < m; ++i) {
- std::cin >> request;
- if (request == '1') {
- int left = 0, right = 0;
- std::cin >> left;
- std::cin >> right;
- treap.Reverse(left, right);
- // treap.Print();
- // treap.Print();
- // treap.Print();
- } else {
- int left = 0, right = 0;
- std::cin >> left >> right;
- std::cout << treap.GetMin(left, right) << "\n";
- }
- }
- treap.Clear();
- // std::cout << "---\n";
- // treap.Print();
- }
- int main() {
- Requests();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement