Cod sursa(job #3301127)

Utilizator MihaelaCismaruMihaela Cismaru MihaelaCismaru Data 21 iunie 2025 20:16:25
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.56 kb
#include<fstream>
#include<stdlib.h>
#include<time.h>
using namespace std;
ifstream in("secv8.in");
ofstream out ("secv8.out");

struct node {
    int randv;
    int val;
    int size;
    node * left;
    node * right;
    node (int value) {
        this->randv = rand();
        this->val = value;
        this->size = 1;
        this->left = NULL;
        this->right = NULL;
    }
};

struct triplet {
    node * left;
    node * middle;
    node * right;
};

node * merge (node * ltree, node * rtree) {
    if (ltree == NULL) {
        return rtree;
    }
    if (rtree == NULL) {
        return ltree;
    }
    if (ltree == rtree) {
        return ltree;
    }
    if (ltree->randv < rtree->randv) {
        ltree->size += rtree->size;
        ltree->right = merge (ltree->right, rtree);
        return ltree;
    }
    else {
        rtree->size += ltree->size;
        rtree->left = merge (ltree, rtree->left);
        return rtree;
    }
}

pair<node*, node*> split (node * root, int x) {
    if (root == NULL) {
        return {NULL, NULL};
    }
    int l_size = root->left  == NULL ? 0 : root->left->size;
    int r_size = root->right == NULL ? 0 : root->right->size;
    if (l_size+1 == x) {
        root->size -= r_size;
        node * aux = root->right;
        root->right = NULL;
        return {root, aux};
    }
    if (l_size >= x) {
        root->size -= l_size;
        pair<node*, node*> trees = split (root->left, x);
        root->left = NULL;
        return {trees.first, merge (trees.second, root)};
    }
    else {
        root->size -= r_size;
        pair<node*, node*> trees = split (root->right, x-(l_size+1));
        root->right = NULL;
        return {merge (root, trees.first), trees.second};
    }
}

node * insert (node * root, int k, int e) {
    if (root == NULL) {
        return new node (e);
    }
    pair<node*, node*> trees = split (root, k-1);
    
    return merge (merge (trees.first, new node (e)), trees.second);
}


int query (node * root, int k) {
    if (root == NULL) {
        return 0;
    }
    int l_size = root->left == NULL ? 0 : root->left->size;
    if (l_size+1 == k) {
        return root->val;
    }
    if (l_size >= k) {
        return query (root->left, k);
    }
    else {
        return query (root->right, k - (l_size + 1));
    }
}

void print_tree (node * root) {
    if (root == NULL) {
        return;
    }
    print_tree (root->left);
    out << root->val << " ";
    print_tree (root->right);
}


triplet * split_interval (node * root, int i, int j) {
    if (root == NULL) {
        return NULL;
    }
    triplet * result = new triplet ();
    pair<node*, node*> trees;

    trees = split (root, i-1);
    result->left = trees.first;

    trees = split (trees.second, j-i+1);
    result->middle = trees.first;
    result->right = trees.second;
    return result;
}

node * delete_interval (node * root, int i, int j) {
    if (root == NULL) {
        return NULL;
    }
    triplet * trees = split_interval (root, i, j);
    return merge (trees->left, trees->right);
}

pair<node*, node*> reverse_interval (node * root, node * root_reversed, int i, int j, int N) {
    if (root == NULL || root_reversed == NULL) {
        return {NULL,NULL};
    }
    triplet * trees = split_interval (root, i, j);
    triplet * trees_reverted = split_interval (root_reversed, N-j+1, N-i+1);

    return {merge (merge (trees->left, trees_reverted->middle), trees->right),
            merge (merge(trees_reverted->left, trees->middle), trees_reverted->right)};
}

int main (void) {
    srand (time(NULL));
    int T, NoUse, k, e, i, j;
    node * root = NULL;
    node * root_reversed = NULL;
    in >> T >> NoUse;
    for (int us = 1; us <= T; us ++) {
        char instruct;
        in >> instruct;
        int N = root == NULL ? 0 : root->size;
        pair<node*, node*> result;
        switch (instruct) {
            case 'I':
                in >> k >> e;
                root = insert (root, k, e);
                root_reversed = insert (root_reversed, N-k+2, e);
            break;
            case 'A':
                in >> k;
                out << query (root, k) << "\n";
            break;
            case 'R':
                in >> i >> j;
                result = reverse_interval (root, root_reversed, i, j, N);
                root = result.first;
                root_reversed = result.second;
            break;
            case 'D':
                in >> i >> j;
                root = delete_interval (root, i, j);
                root_reversed = delete_interval (root_reversed, N-j+1, N-i+1);
            break;
        }
    }
    print_tree(root); out <<"\n";
    return 0;
}