Cod sursa(job #1785795)

Utilizator PenaluPenalu Ion Penalu Data 21 octombrie 2016 23:04:10
Problema Secv8 Scor 55
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.16 kb
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>

using namespace std;

int my_rand() {
    return rand()%(1<<15)*(1<<15) + rand()%(1<<15);
}

struct node {
    int val, prio, sub;
    int sw;
    node *l, *r;

    node(int val) : val(val) {
        prio = my_rand();
        l = NULL;
        r = NULL;
        sw = false;
        sub = 1;
    }

    int left() {
        return (l == NULL ? 0 : l->sub);
    }

    void update() {
        sub = 1;
        if (l != NULL)
            sub += l->sub;
        if (r != NULL)
            sub += r->sub;
    }

    void lazy() {
        if (sw) {
            swap(l, r);
            if (l != NULL)
                l->sw ^= 1;
            if (r != NULL)
                r->sw ^= 1;
            sw = false;
        }
    }
}*T;

// Everything < k in L, everything else in R.
void split(node* T, node*& L, node*& R, int k) {
    if (T == NULL) {
        L = NULL;
        R = NULL;
        return;
    }

    T->lazy();

    if (T->left() + 1 < k) {
        L = T;
        split(T->r, L->r, R, k-T->left()-1);
        L->update();
    } else {
        R = T;
        split(T->l, L, R->l, k);
        R->update();
    }
}

void join(node*& T, node* L, node* R) {
    if (L == NULL) {
        T = R;
        return;
    }
    if (R == NULL) {
        T = L;
        return;
    }

    L->lazy();
    R->lazy();

    if(L->prio < R->prio) {
        T = L;
        join(T->r, L->r, R);
        T->update();
    } else {
        T = R;
        join(T->l, L, R->l);
        T->update();
    }
}

void insert(node*& T, node* d, int k) {
    if (T == NULL) {
        T = d;
        return;
    }

    T->lazy();

    if (d->prio < T->prio) {
        node *L, *R;
        split(T, L, R, k);
        T = d;
        T->l = L;
        T->r = R;
        T->update();
        return;
    }

    if (T->left() >= k-1) {
        insert(T->l, d, k);
    } else {
        insert(T->r, d, k-T->left()-1);
    }
    T->update();
}

void insert(int k, int e) {
    node *d = new node(e);
    insert(T, d, k);
}

int find(node*& T, int k) {
    T->lazy();

    if (T->left()+1 == k) {
        return T->val;
    }

    if (T->left() >= k-1) {
        return find(T->l, k);
    } else {
        return find(T->r, k-T->left()-1);
    }
}

int find(int k) {
    return find(T, k);
}

void reverse(int i, int j) {
    node *TT, *T1, *T2, *T3;
    split(T, TT, T3, j+1);
    split(TT, T1, T2, i);
    if (T2 != NULL) {
        T2->sw ^= 1;
    }
    join(TT, T1, T2);
    join(T, TT, T3);
}

void erase(node*& T, int k) {
    T->lazy();
    if (T->left() + 1 == k) {
        node *L, *R;
        L = T->l;
        R = T->r;
        delete T;
        T = NULL;
        join(T, L, R);
        if (T != NULL)
            T->update();
        return;
    }

    if (T->left() >= k-1) {
        erase(T->l, k);
    } else {
        erase(T->r, k-T->left()-1);
    }
    if (T != NULL)
        T->update();
}

void erase(int k) {
    erase(T, k);
}

void dfs(node* T) {
    T->lazy();
    if (T->l != NULL) {
        dfs(T->l);
    }
    cout << T->val << " ";
    if (T->r != NULL) {
        dfs(T->r);
    }
}

void print_all() {
    dfs(T);
}

int main()
{
    freopen("secv8.in", "r", stdin);
    freopen("secv8.out", "w", stdout);
    srand(time(NULL));
    int n, d;
    cin >> n >> d;

    for (int i = 1; i <= n; ++i) {
        char c;
        cin >> c;
        if (c == 'I') {
            int k, e;
            cin >> k >> e;
            insert(k, e);
        }
        if (c == 'A') {
            int k;
            cin >> k;
            cout << find(k) << '\n';
        }
        if (c == 'R') {
            int i, j;
            cin >> i >> j;
            reverse(i, j);
        }
        if (c == 'D') {
            int i, j;
            cin >> i >> j;
            for (int k = i; k <= j; ++k) {
                erase(i);
            }
        }
        // cout << c << " ";
        // print_all();
        // cout << "\n";
        //cout.flush();
    }

    print_all();
}