Cod sursa(job #3301111)

Utilizator MihaelaCismaruMihaela Cismaru MihaelaCismaru Data 21 iunie 2025 19:20:45
Problema Secv8 Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.2 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);
}

node * reverse_tree (node * root) {
    if (root == NULL) {
        return NULL;
    }
    reverse_tree (root->left);
    reverse_tree (root->right);
    swap (root->left, root->right);
    return root;
}

node * reverse_interval (node * root, int i, int j) {
    if (root == NULL) {
        return NULL;
    }
    triplet * trees = split_interval (root, i, j);

    trees->middle = reverse_tree (trees->middle);

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

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