Cod sursa(job #2307397)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 24 decembrie 2018 15:05:49
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.46 kb
#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <ctime>

using namespace std;

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

const int NMAX = 400005;

struct Treap { /// popovici
    int sz, l, r, val, p;
    bool rev;
};

Treap T[NMAX];
int R, nodes;

void add(int val) {
    ++ nodes;
    T[nodes].val = val;
    T[nodes].p = rand();
}

void lazy(int node) {
    if(node == 0)
        return;
    int l = T[node].l;
    int r = T[node].r;

    if(T[node].rev) {
        swap(T[node].l, T[node].r);

        T[node].rev = 0;
        T[l].rev ^= 1;
        T[r].rev ^= 1;
    }
}

int key(int node) {
    return T[T[node].l].sz + 1;
}

void update(int node) {
    if(node == 0)
        return;

    int l = T[node].l;
    int r = T[node].r;
    T[node].sz = T[l].sz + T[r].sz + 1;
}

void split(int root, int &l, int &r, int pos) {
    lazy(root);
    if(root == 0)
        l = r = 0;
    else {
        int k = key(root);
        if(k >= pos) {
            split(T[root].l, l, T[root].l, pos);
            r = root;
        } else {
            split(T[root].r, T[root].r, r, pos - k);
            l = root;
        }
    }
    update(root);
}

void toinsert(int &root, int node, int pos) {
    lazy(root);
    int k = key(root);

    if(T[node].p <= T[root].p) {
        if(pos <= k)
            toinsert(T[root].l, node, pos);
        else
            toinsert(T[root].r, node, pos - k);
    } else {
        split(root, T[node].l, T[node].r, pos);
        root = node;
    }
    update(root);
}

int acces(int node, int pos) {
    lazy(node);

    int k = key(node);
    if(pos == k)
        return T[node].val;
    if(pos < k)
        return acces(T[node].l, pos);
    if(pos > k)
        return acces(T[node].r, pos - k);
}

void join(int &root, int l, int r) {
    lazy(root);
    lazy(l);
    lazy(r);

    if(!l || !r)
        root = l + r; /// cazul asta?
   else {
        if(T[l].p >= T[r].p) {
            join(T[l].r, T[l].r, r);
            root = l;
        } else {
            join(T[r].l, l, T[r].l);
            root = r;
        }
   }
   update(root);
}

void toreverse(int &root, int a, int b) {
    int x, y, z;
    split(root, x, y, b + 1);
    split(x, x, z, a);

    T[z].rev ^= 1;

    join(x, x, z);
    join(root, x, y);
}

void toerase(int &root, int a, int b) {
    int x, y, z;
    split(root, x, y, b + 1);
    split(x, x, z, a);

    join(root, x, y);
}

void finalstate(int node) {
    if(node == 0)
        return;
    lazy(node);
    finalstate(T[node].l);
    out << T[node].val << " ";
    finalstate(T[node].r);
}

int main() {
    int n, un_pisat;
    in >> n >> un_pisat;
    srand(time(NULL));

    while(n --) {
        char type;
        in >> type;

        if(type == 'I') {
            int pos, el;
            in >> pos >> el;
            add(el);
            toinsert(R, nodes, pos);
        }
        if(type == 'A') {
            int k;
            in >> k;
            out << acces(R, k) << "\n";
        }
        if(type == 'R') {
            int i, j;
            in >> i >> j;
            toreverse(R, i, j);
        }
        if(type == 'D') {
            int i, j;
            in >> i >> j;
            toerase(R, i, j);
        }
    }
    finalstate(R);

    return 0;
}