Cod sursa(job #2209397)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 3 iunie 2018 11:50:51
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.33 kb
#include <iostream>
#include <fstream>
#include <ctime>
#include <cstdlib>

using namespace std;

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

struct Treap {

  int prio;
  int sz;
  int val;

  bool rev;

  Treap *le , *ri;

  Treap(int val) {
    prio = rand();
    sz = 1;
    this->val = val;
    rev = 0;
    le = ri = NULL;
  }

  void compute() {
    clean();
    sz = 1;
    if(le != NULL)
      sz += le->sz;
    if(ri != NULL)
      sz += ri->sz;
  }

  void clean() {
    if(rev == 1){
      Treap *aux = le;
      le = ri;
      ri = aux;

      if(le != NULL)
        le->rev ^= rev;
      if(ri != NULL)
        ri->rev ^= rev;
      rev = 0;
    }
  }
};

int getsz(Treap * node) {
  if(node == NULL)
    return 0;
  else
    return node->sz;
}


void merge(Treap *left, Treap *right, Treap* &node) {
  if(left == NULL) {
    node = right;
  } else if(right == NULL){
    node = left;
  } else {
    left->compute();
    right->compute();
    if(left->prio < right->prio){
      merge(left, right->le , right->le);
      node = right;
    } else {
      merge(left->ri , right , left->ri);
      node = left;
    }
  }
  if(node != NULL)
    node->compute();
}

void split(Treap* node, Treap* &left , Treap* &right , int pos) { //pos = target
  if(node == NULL)
    left = right = NULL;
  else {
    node->compute();
    if(getsz(node->le) + 1 <= pos){
      split(node->ri , node->ri , right , pos - getsz(node->le) - 1);
      left = node;
      left->compute();
    } else {
      split(node->le , left , node->le , pos);
      right = node;
      right->compute();
    }
  }
}

//====================================================

void insert(Treap* &root, int x , int val) {
  Treap *left , *left2, *right;

  split(root , left , right , x - 1);
  Treap *node = new Treap(val);

  merge(left , node , left2);
  merge(left2 , right , root);
}

int access(Treap* &root , int x) {
  Treap *left , *right, *leftleft , *leftright;

  split(root , left , right , x);
  split(left , leftleft , leftright , x - 1);
  int result = leftright->val;
  merge(leftleft , leftright , left);
  merge(left , right , root);
  return result;
}

void sdelete(Treap* &root , int x , int y) {
  Treap *left , *right, *leftleft , *leftright;

  split(root , left , right , y);
  split(left , leftleft , leftright , x - 1);

  merge(leftleft , right , root);
}

void reverse(Treap* &root , int x , int y) {
  Treap *left , *right, *leftleft , *leftright;

  split(root , left , right , y);
  split(left , leftleft , leftright , x - 1);
  leftright->rev ^= 1;

  merge(leftleft , leftright , left);
  merge(left , right , root);
}

int main(){
  srand(time(NULL));
  Treap *root = NULL;

  int n , z;
  in >> n >> z;
  for(int i = 1 ; i <= n ;i++){
    char op;
    in >> op;
    if(op == 'I'){
      int x , val;
      in >> x >> val;
      insert(root , x , val);
    } else if(op == 'A'){
      int k;
      in >> k;
      out << access(root , k) << '\n';
    } else if(op == 'R'){
      int x , y;
      in >> x >> y;
      reverse(root , x , y);
    } else{
      int x , y;
      in >> x >> y;
      sdelete(root , x , y);
    }
  }
  for(int j = 1 ; j <= root->sz ; j++)
    out << access(root , j) << " ";
  return 0;
}