Cod sursa(job #2206783)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 23 mai 2018 19:55:17
Problema Secv8 Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.99 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstdlib>

using namespace std;

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

const int INF = 2e9;

class Treap {
public:

  Treap () {
    R = NILL = new Node (0, 0, 0, nullptr, nullptr);
  }

  void Print () {
    m_Print (R);
    fout << '\n';
  }

  void Insert (int value, int position) {
    m_Insert (value, rand () + 1, position, R);
  }

  void Access (int position) {
    m_Access (position, R);
  }

  void Reverse (int i, int j) {
    m_Reverse (i, j);
  }

  void Remove (int i, int j) {
    m_Remove (i, j);
  }

private:

  struct Node {

    Node (int v, int h, int p, Node *l, Node *r) { 
   
      this -> value = v;
      this -> howMany = h;
      this -> priority = p;
      this -> left = l;
      this -> right = r;
      this -> lazy = false;
    }

    bool lazy;
    Node *left, *right;
    int value, howMany, priority;
  };

  Node *R, *NILL;
  
  void m_Print (Node *&curNode) {

    if (curNode == NILL) {
      return;
    }

    m_Propagate (curNode);

    m_Print (curNode -> left);
    fout << curNode -> value << ' ';
    m_Print (curNode -> right);
  }

  void m_UpdateHM (Node *&curNode) {

    if (curNode == NILL) {
      return;
    }

    curNode -> howMany = curNode -> left -> howMany + curNode -> right -> howMany + 1;
  }

  void m_Prop (Node *&curNode) {

    if (curNode == NILL) {
      return;
    }

    curNode -> left -> lazy ^= curNode -> lazy;
    curNode -> right -> lazy ^= curNode -> lazy;

    if (curNode -> lazy) {
      swap (curNode -> left, curNode -> right);
      curNode -> lazy = false;
    }
  }

  void m_Propagate (Node *&curNode) {

    m_Prop (curNode);
    m_Prop (curNode -> left);
    m_Prop (curNode -> right);
  }

  void m_RotateLeft (Node *&curNode) {

    Node *aux = curNode -> right;
    curNode -> right = curNode -> right -> left;
    aux -> left = curNode;
    curNode = aux;

    m_UpdateHM (curNode -> left);
    m_UpdateHM (curNode);
  }

  void m_RotateRight (Node *&curNode) {
  
    Node *aux = curNode -> left;
    curNode -> left = curNode -> left -> right;
    aux -> right = curNode;
    curNode = aux;

    m_UpdateHM (curNode -> right);
    m_UpdateHM (curNode);
  }

  void m_Balance (Node *&curNode) {

    if (curNode -> priority < curNode -> left -> priority) {
      m_RotateRight (curNode);
    }
    else if (curNode -> priority < curNode -> right -> priority) {
      m_RotateLeft (curNode);
    }
  }

  void m_Insert (int value, int priority, int position, Node *&curNode) {

    if (curNode == NILL) {
      curNode = new Node (value, 1, priority, NILL, NILL);
      return;
    }
 
    m_Propagate (curNode);

    if (curNode -> left -> howMany + 1 >= position) {
      m_Insert (value, priority, position, curNode -> left);
    }
    else {
      m_Insert (value, priority, position - curNode -> left -> howMany - 1, curNode -> right);
    }

    m_UpdateHM (curNode);
    m_Balance (curNode);
  }

  void m_Erase (Node *&curNode) {
  
    if (curNode == NILL) {
      return;
    }

    m_Propagate (curNode);

    if (curNode -> left == NILL and curNode -> right == NILL) {
      delete curNode;
      curNode = NILL;
      return;
    }

    if (curNode -> left -> priority < curNode -> right -> priority) {
      m_RotateLeft (curNode);
      m_Erase (curNode -> left);
    }
    else {
      m_RotateRight (curNode);
      m_Erase (curNode -> right);
    }

    m_UpdateHM (curNode);
    m_Balance (curNode);
  }

  void m_Access (int position, Node *&curNode) {

    m_Propagate (curNode);

    if (curNode -> left -> howMany + 1 == position) {
      fout << curNode -> value << '\n';
      return;
    }

    if (curNode -> left -> howMany + 1 > position) {
      m_Access (position, curNode -> left);
    }
    else {
      m_Access (position - curNode -> left -> howMany - 1, curNode -> right);
    }
  }

  void m_Split (int position, Node *&l, Node *&r) {

    m_Insert (0, INF, position, R);
    l = R -> left;
    r = R -> right;
    delete R;
  }

  void m_Join (Node *l, Node *r) {

    R = new Node (-1, 0, INF, l, r);
    m_Erase (R);
  }

  void m_Reverse (int i, int j) {
  
    Node *l, *m, *r;

    m_Split (i, l, m);
    R = m;
    m_Split (j - i + 2, m, r);
    
    m -> lazy ^= 1;
    m_Propagate (m);

    m_Join (l, m);
    m = R;
    m_Join (m, r);
  }

  void m_Remove (int i, int j) {

    Node *l, *m, *r;

    m_Split (i, l, m);
    R = m;
    m_Split (j - i + 2, m, r);

    m_Join (l, r);
  }
};

int main () {

  srand (27);

  Treap *t = new Treap ();
  
  int n, k;
  fin >> n >> k;

  while (n --) {

    char type; 
    fin >> type;
  
    if (type == 'I') {
      int value, position;
      fin >> position >> value;
      t -> Insert (value, position);
    }
    else if (type == 'A') {
      int position;
      fin >> position;
      t -> Access (position);
    }
    else if (type == 'R') {
      int i, j;
      fin >> i >> j;
      t -> Reverse (i, j);
    }
    else if (type == 'D') {
      int i, j;
      fin >> i >> j;
      t -> Remove (i, j);
    }
  }

  t -> Print ();
}