Cod sursa(job #2032375)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 4 octombrie 2017 21:29:35
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.07 kb
#include <bits/stdc++.h>

using namespace std;

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

const int inf = 2e9, vaal = (1<<15) - 1;
int Q, pos, x, y, val; char tip;

int MyRand()
{
    return ((rand()&vaal)<<15) | (rand()&vaal);
}

struct rules
{
    int val, prio, sz;
    bool rev;
    rules *left, *right;

    rules()
    {
        left = right = NULL;
        sz = prio = val = 0; rev = 0;
    }

    rules(rules *_left, rules *_right, int _prio, int _val)
    {
        rev = 0;
        left = _left, right = _right;
        prio = _prio; val = _val;
        sz = left->sz + right->sz + 1;
    }
} *root, *noo;


void refresh_size(rules *t)
{
    t->sz = t->left->sz + t->right->sz + 1;
}

void refresh_reversed(rules *t)
{
    if(!t->rev || t == noo) return;
    t->rev = 0;

    swap(t->left, t->right);
    t->left->rev ^= 1;
    t->right->rev ^= 1;
}

void rotate_left(rules *&t)
{
    refresh_reversed(t->left);
   /// refresh_reversed(t->right);

    rules *aux = t->left;
    t->left = aux->right;
    aux->right = t;
    t = aux;

    refresh_size(t->right);
    refresh_size(t);
}

void rotate_right(rules *&t)
{
  ///  refresh_reversed(t->left);
    refresh_reversed(t->right);

    rules *aux = t->right;
    t->right = aux->left;
    aux->left = t;
    t = aux;

    refresh_size(t->left);
    refresh_size(t);
}

void balance(rules *&t)
{
    if(t->left->prio > t->prio) rotate_left(t);
        else if(t->right->prio > t->prio) rotate_right(t);
}

void insert_rules(rules *&t, int value, int pos, int prio)
{
    if(t == noo)
    {
        t = new rules(noo, noo, prio, value);
        return;
    }

    refresh_reversed(t);
    if(pos <= t->left->sz) insert_rules(t->left, value, pos, prio);
        else insert_rules(t->right, value, pos - t->left->sz - 1, prio);

    refresh_size(t);
    balance(t);
}

int acces_rules(rules *&t, int pos)
{
    refresh_reversed(t);
    if(t->left->sz + 1 == pos) return t->val;
    if(pos <= t->left->sz) return acces_rules(t->left, pos);
        else return acces_rules(t->right, pos - t->left->sz - 1);
}

void delete_rules(rules *&t, int pos)
{
    if(t->left == noo && t->right == noo)
    {
        delete t;
        t = noo;
        return;
    }

    refresh_reversed(t);
    if(t->left->sz + 1 == pos)
    {
        if(t->left->prio > t->right->prio)
        {
            refresh_reversed(t->left);
            rotate_left(t);
          ///  refresh_reversed(t->right);
            delete_rules(t->right, t->right->left->sz + 1);
        }
        else
        {
            refresh_reversed(t->right);
            rotate_right(t);
          ///  refresh_reversed(t->left);
            delete_rules(t->left, t->left->left->sz + 1);
        }
    }
    else if(pos <= t->left->sz) delete_rules(t->left, pos);
        else delete_rules(t->right, pos - t->left->sz - 1);

    refresh_size(t);
}

pair<rules*, rules*> split(rules *&t, int pos)
{
    insert_rules(t, -1, pos, inf);
    return {t->left, t->right};
}

rules* join(rules *t1, rules *t2)
{
    rules *t = new rules(t1, t2, inf, -1);
    delete_rules(t, t->left->sz + 1);
    return t;
}

void reverse_rules(rules *&t, int x, int y)
{
    pair<rules*, rules*> one, two;
    one = split(t, y);
    two = split(one.first, x-1);

    two.second -> rev ^= 1;
    t = join(join(two.first, two.second), one.second);
}

void print_rules(rules *&t)
{
    if(t == noo) return;
    refresh_reversed(t);
    print_rules(t->left);
    fout << (t->val) << ' ';
    print_rules(t->right);
}

int main()
{
    srand(time(0));
    root = noo = new rules();

    fin >> Q >> tip;
    while(Q--)
    {
        fin >> tip;
        if(tip == 'I')
        {
            fin >> pos >> val;
            insert_rules(root, val, pos-1, MyRand());
        }
        else if(tip == 'A')
        {
            fin >> pos;
            fout << acces_rules(root, pos) << '\n';
        }
        else if(tip == 'R')
        {
            fin >> x >> y;
            reverse_rules(root, x, y);
        }
        else
        {
            fin >> x >> y;
            while(y >= x) delete_rules(root, x), y--;
        }
    }

    print_rules(root);
    return 0;
}