Cod sursa(job #2038862)

Utilizator mihail.jianuJianu Mihail mihail.jianu Data 14 octombrie 2017 01:55:31
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.66 kb
#include <iostream>
#include <algorithm>
#include <random>
#include <ctime>
#include <cmath>
#include <fstream>

using namespace std;

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

class Treap;

int randomize(){
    int r = rand() + rand() * rand();
    return fabs(r);
}

class Treap {
public:
    int val, key, size;
    bool reversed;
    Treap *left, *right;


    Treap() {
        val = 0;
        key = 0;
        left = nullptr;
        right = nullptr;
        reversed = false;
        size = 0;
    }
    Treap(int _val, int _key);
    void propagate();
    void update();
    Treap* join(Treap *that);
    pair<Treap*, Treap*> split(int l);
    Treap* insert(int x, int p);
    Treap* ddelete(int l, int r);
    Treap* reverse(int l, int r);
    pair<Treap*, int> access(int p);
    void print();
    ~Treap();
};

Treap *nil = new Treap();

Treap :: Treap(int _val, int _key = randomize()) {
    val = _val;
    key = _key;
    left = nil;
    right = nil;
    reversed = false;
    size = 1;
}

Treap::~Treap() {
    if(this != nullptr) {
        if(left != nil) {
            left = nullptr;
            delete left;
        }
        if(right != nil) {
            right = nullptr;
            delete right;
        }
    }
}

void Treap :: update() {
    if(this != nil)
        this->size = this->left->size + 1 + this -> right -> size;
}

void Treap :: propagate() {
    if(this->reversed && this != nil){
        this->reversed = false;
        this->left->reversed = !this->left->reversed;
        this->right->reversed = !this->right->reversed;
        swap(this->left, this->right);
    }
}

Treap* Treap :: join(Treap *that) {
    this->propagate();
    that->propagate();
    if (this == nil)
        return that;
    if (that == nil)
        return this;
    if(this->key > that->key) {
        this->right = this->right->join(that);
        this->right->update();
        return this;
    }
    else{
        that->left = this->join(that->left);
        that->left->update();
        return that;
    }
}

pair <Treap*, Treap*> Treap :: split(int l) {
    this->propagate();
    if(this == nil)
        return {nil, nil};
    if(l <= this->left->size) {
        pair <Treap*, Treap*> sp = this->left -> split(l);
        this->left = sp.second;
        this->left->update();
        return {sp.first, this};
    }
    else{
        pair <Treap*, Treap*> sp = this -> right -> split(l - this->left->size -  1);
        this->right = sp.first;
        this->right->update();
        return {this, sp.second};
    }
}

Treap* Treap :: insert(int x, int p) {
    pair <Treap*, Treap*> sp = this->split(p);
    Treap *node = new Treap(x);
    sp.first = sp.first->join(node);
    sp.first = sp.first->join(sp.second);
    return sp.first;
}

Treap* Treap :: ddelete(int l, int r) {
    pair <Treap*, Treap*> sp1 = this->split(l);
    pair <Treap*, Treap*> sp2 = sp1.second->split(r - l);
    delete sp2.first;
    sp1.first = sp1.first->join(sp2.second);
    return sp1.first;
}

pair <Treap*, int> Treap :: access(int p) { /// the element on position p
    int ans;
    pair <Treap*, Treap*> sp1 = this->split(p);
    pair <Treap*, Treap*> sp2 = sp1.second->split(1);
    ans = sp2.first->val;
    sp1.second = sp2.first->join(sp2.second);
    sp1.first = sp1.first->join(sp1.second);
    return {sp1.first, ans};
}

void Treap :: print() {
    if(this == nil)
        return;
    this->propagate();
    this->left->print();
    out << this->val << " ";
    this->right->print();
}

Treap* Treap :: reverse(int l, int r) { /// reverse the order of the elements in a treap, from l to r
    pair <Treap*, Treap*> sp1 = this->split(l);
    pair <Treap*, Treap*> sp2 = sp1.second->split(r - l);
    sp2.first->reversed=true;
    sp1.second = sp2.first->join(sp2.second);
    sp1.first = sp1.first->join(sp1.second);
    return sp1.first;
}

void init(){
    srand(time(NULL));
}

int main() {
    init();

    int q, u;
    char c;
    Treap *t = nil;

    in >> q >> u;

    while(q--) {
        in >> c;
        int i, j, k, e;
        pair <Treap*, int> p;

        if(c == 'I') {
            in >> k >> e;
            t = t->insert(e, k - 1);
        }
        else if(c == 'A') {
            in >> k;
            p = t -> access(k - 1);
            t = p.first;
            out << p.second << "\n";
        }
        else if(c == 'R') {
            in >> i >> j;
            t = t->reverse(i - 1, j);
        }
        else{
            in >> i >> j;
            t = t->ddelete(i - 1, j);
        }
    }

    t->print();
    return 0;
}