Cod sursa(job #2498588)

Utilizator ContDeRacistAliniateEBlat ContDeRacist Data 24 noiembrie 2019 05:33:15
Problema Secv8 Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.27 kb
///Lulu a bagat eu m-am uitat(cat de cat i-am mai zis acolo mici detalii sper ca nu am fost useless)

#include <bits/stdc++.h>

using namespace std;

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

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>

mt19937 rnd((long long)(new char));

struct Treap{
  int key;
  int prio;
  int rev;
  int sz;
  Treap* left;
  Treap* right;
};
Treap* emptyTreap = new Treap{0, 0, 0, 0, NULL, NULL};

void clean(Treap* &root){
  if(root == emptyTreap)
    return ;
  if(root->left != emptyTreap)
    root->left->rev ^= root->rev;
  if(root->right != emptyTreap)
    root->right->rev ^= root->rev;
  if(root->rev == 1)
    swap(root->left, root->right);
  root->rev = 0;
}

void computenode(Treap* &root){
  root->sz = 1;
  if(root->left != emptyTreap)
    root->sz += root->left->sz;
  if(root->right != emptyTreap)
    root->sz += root->right->sz;
}

void split(Treap* root, int pos, Treap* &leftsol, Treap* &rightsol){
  if(root == emptyTreap) {
    leftsol = rightsol = emptyTreap;
    return ;
  }
  clean(root);
  if(root->left->sz + 1 <= pos) {
    leftsol = root;
    split(root->right, pos - root->left->sz - 1, leftsol->right, rightsol);
    computenode(leftsol);
  } else {
    rightsol = root;
    split(root->left, pos, leftsol, rightsol->left);
    computenode(rightsol);
  }
}

void mergep(Treap* leftsol, Treap* rightsol, Treap* &result){
  if(leftsol == emptyTreap && rightsol == emptyTreap)
    result = emptyTreap;
  else if(leftsol == emptyTreap)
    result = rightsol;
  else if(rightsol == emptyTreap)
    result = leftsol;
  else {
    clean(leftsol);
    clean(rightsol);
    if(leftsol->prio < rightsol->prio){
      result = rightsol;
      mergep(leftsol, rightsol->left, result->left);
      computenode(result);
    } else {
      result = leftsol;
      mergep(leftsol->right, rightsol, result->right);
      computenode(result);
    }
  }
}

void insertelm(Treap* &root, int pos, int val){
  Treap *leftsol, *rightsol;
  split(root, pos - 1, leftsol, rightsol);
  Treap* treapnou = new Treap{val, rnd(), 0, 1, emptyTreap, emptyTreap};
  mergep(leftsol, treapnou, leftsol);
  mergep(leftsol, rightsol, root);
}

int acces(Treap* &root, int pos){
  Treap *leftsol, *rightsol;
  split(root, pos, leftsol, rightsol);
  Treap *leftleft, *leftright;
  split(leftsol, pos - 1, leftleft, leftright);
  int result = leftright->key;
  mergep(leftleft, leftright, leftsol);
  mergep(leftsol, rightsol, root);
  return result;
}

void printTreap(Treap* &root){
  //cout << ":";
  if(root == emptyTreap)
    return ;
  clean(root);

  printTreap(root->left);
  out << root->key << " ";
  printTreap(root->right);
}

void reverseinterval(Treap* &root, int pos1, int pos2){
  Treap* leftsol, *rightsol;
  split(root, pos2, leftsol, rightsol);
  Treap* leftleft, *leftright;
  split(leftsol, pos1 - 1, leftleft, leftright);
  leftright->rev ^= 1;
  mergep(leftleft, leftright, leftsol);
  mergep(leftsol, rightsol, root);
}
void deleteinterval(Treap* &root, int pos1, int pos2){
  Treap *leftsol, *rightsol;
  split(root, pos2, leftsol, rightsol);
  Treap* leftleft, *leftright;
  split(leftsol, pos1 - 1, leftleft, leftright);
  mergep(leftleft, rightsol, root);
}


int main()
{
    /*
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    */

    Treap* root = emptyTreap;
    printTreap(root);
    //*
    int n, m;
    in >> n >> m;
    for(int i = 1;i <= n; i++){
        char op;
        in >> op;
        if(op == 'I') {
            int pos, val;
            in >> pos >> val;
            insertelm(root, pos, val);
        } else if(op == 'A'){
            int pos;
            in >> pos;
            out << acces(root, pos) << '\n';
        } else if(op == 'R'){
            int pos1, pos2;
            in >> pos1 >> pos2;
            reverseinterval(root, pos1, pos2);
        } else if(op == 'D'){
            int pos1, pos2;
            in >> pos1 >> pos2;
            deleteinterval(root, pos1, pos2);
        }
    }
    printTreap(root);
    //*/

    return 0;
}