Cod sursa(job #3233450)

Utilizator BuzdiBuzdugan Rares Andrei Buzdi Data 3 iunie 2024 14:49:44
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.76 kb
#include <fstream>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <cassert>
#include <set>
#include <map>
#include <cstdlib>
#include <ctime>
#define ll long long

using namespace std;

ifstream cin("secv8.in");
ofstream cout("secv8.out");

struct Node {
    int x;
    bool to_reverse;
    int sub_tree_size, priority;
    Node *left, *right;

    Node(int x) {
        this->x = x;
        to_reverse = 0;
        sub_tree_size = 1;
        priority = rand();
        left = right = NULL;
    }
}*root;

int n, useless;

int GetSubTreeSize(Node* root) {
    return (root ? root->sub_tree_size : 0);
}

void UpdateLazy(Node* root) {
    if(!root || !root->to_reverse) {
        return;
    }

    swap(root->left, root->right);
    if(root->left) {
        root->left->to_reverse ^= 1;
    }
    if(root->right) {
        root->right->to_reverse ^= 1;
    }
    root->to_reverse = 0;
}

void Split(Node* root, Node*& left_tree, Node*& right_tree, int value) {
    if(!root) {
        left_tree = right_tree = NULL;
        return;
    }

    UpdateLazy(root);
    int sub_tree_size_left = GetSubTreeSize(root->left);
    if(sub_tree_size_left + 1 <= value) {
        Split(root->right, root->right, right_tree, value - sub_tree_size_left - 1);
        left_tree = root;
    }
    else {
        Split(root->left, left_tree, root->left, value);
        right_tree = root;
    }

    root->sub_tree_size = GetSubTreeSize(root->left) + GetSubTreeSize(root->right) + 1;
}

void Merge(Node*& root, Node* left_tree, Node* right_tree) {
    UpdateLazy(left_tree);
    UpdateLazy(right_tree);

    if(left_tree == NULL) {
        root = right_tree;
        return;
    }
    if(right_tree == NULL) {
        root = left_tree;
        return;
    }

    if(left_tree->priority > right_tree->priority) {
        Merge(left_tree->right, left_tree->right, right_tree);
        root = left_tree;
    }
    else {
        Merge(right_tree->left, left_tree, right_tree->left);
        root = right_tree;
    }

    root->sub_tree_size = GetSubTreeSize(root->left) + GetSubTreeSize(root->right) + 1;
}

void Insert(int k, int e) {
    Node *A, *B;
    Split(root, A, B, k - 1);
    Merge(root, A, new Node(e));
    Merge(root, root, B);
}

int Acces(int k) {
    Node *A, *B, *C;
    Split(root, A, B, k - 1);
    Split(B, B, C, 1);

    int answer = B->x;

    Merge(root, A, B);
    Merge(root, root, C);
    return answer;
}

void Reverse(int left, int right) {
    Node *A, *B, *C;
    Split(root, A, B, left - 1);
    Split(B, B, C, right - left + 1);

    B->to_reverse ^= 1;

    Merge(root, A, B);
    Merge(root, root, C);
}

void Delete(int left, int right) {
    Node *A, *B, *C;
    Split(root, A, B, left - 1);
    Split(B, B, C, right - left + 1);

    Merge(root, A, C);
}

void Print(Node* root) {
    if(!root) {
        return;
    }

    UpdateLazy(root);
    Print(root->left);
    cout << root->x << ' ';
    Print(root->right);
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    srand(time(NULL));

    cin >> n >> useless;
    while(n--) {
        char type;
        cin >> type;
        if(type == 'I') {
            int k, e;
            cin >> k >> e;
            Insert(k, e);
        }
        else if(type == 'A') {
            int k;
            cin >> k;
            cout << Acces(k) << '\n';
        }
        else if(type == 'R') {
            int left, right;
            cin >> left >> right;
            Reverse(left, right);
        }
        else {
            int left, right;
            cin >> left >> right;
            Delete(left, right);
        }
    }
    Print(root);

    return 0;
}