Cod sursa(job #1509349)

Utilizator vladrochianVlad Rochian vladrochian Data 23 octombrie 2015 19:15:40
Problema Secv8 Scor 25
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.61 kb
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;

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

struct Node {
  Node(int value, int priority, int size, Node *ls, Node *rs)
      : value(value), priority(priority),
        size(size), rev(false), ls(ls), rs(rs) {}

  int value, priority, size;
  bool rev;
  Node *ls, *rs;
} *treap, *nil = new Node(0, -1, 0, nullptr, nullptr);

inline void GetSize(Node *node) {
  node->size = node->ls->size + node->rs->size + 1;
}

inline void UpdateRev(Node *node) {
  if (node != nil && node->rev) {
    swap(node->ls, node->rs);
    node->rev = false;
    node->ls->rev ^= 1;
    node->rs->rev ^= 1;
  }
}

void Update(Node *node) {
  UpdateRev(node);
  UpdateRev(node->ls);
  UpdateRev(node->rs);
  GetSize(node);
}

void RotateLeft(Node *&node) {
  Node *aux = node->rs;
  node->rs = aux->ls;
  aux->ls = node;
  Update(node);
  node = aux;
  Update(node);
}

void RotateRight(Node *&node) {
  Node *aux = node->ls;
  node->ls = aux->rs;
  aux->rs = node;
  Update(node);
  node = aux;
  Update(node);
}

void Insert(Node *&node, int pos, int value, int priority) {
  if (node == nil) {
    node = new Node(value, priority, 1, nil, nil);
    return;
  }

  Update(node);
  if (pos <= node->ls->size + 1)
    Insert(node->ls, pos, value, priority);
  else
    Insert(node->rs, pos - node->ls->size - 1, value, priority);

  if (node->ls->priority > node->priority)
    RotateRight(node);
  else if (node->rs->priority > node->priority)
    RotateLeft(node);
  Update(node);
}

int GetValue(Node *node, int pos) {
  Update(node);
  if (pos == node->ls->size + 1)
    return node->value;

  if (pos <= node->ls->size)
    return GetValue(node->ls, pos);
  else
    return GetValue(node->rs, pos - node->ls->size - 1);
}

void Erase(Node *&node, int pos) {
  Update(node);
  if (pos != node->ls->size + 1) {
    if (pos <= node->ls->size)
      Erase(node->ls, pos);
    else
      Erase(node->rs, pos - node->ls->size - 1);
    Update(node);
    return;
  }

  if (node->ls == nil && node->rs == nil) {
    delete node;
    node = nil;
    return;
  }

  if (node->ls->priority > node->rs->priority) {
    RotateRight(node);
    Erase(node->rs, node->rs->ls->size + 1);
  } else {
    RotateLeft(node);
    Erase(node->ls, node->ls->ls->size + 1);
  }
  Update(node);
}

Node* Split(Node *&node, int pos) {
  Insert(node, pos, 69, 1e9);
  Node *ls = node->ls, *rs = node->rs;
  delete node;
  node = ls;
  return rs;
}

void Join(Node *&node, Node *other) {
  node = new Node(69, 1e9, node->size + other->size + 1, node, other);
  Erase(node, node->ls->size + 1);
}

void Print(Node *node) {
  if (node == nil)
    return;

  Update(node);
  Print(node->ls);
  fout << node->value << " ";
  Print(node->rs);
}

int main() {
  srand(time(0));
  treap = nil;
  int t, rev;
  fin >> t >> rev;

  while (t--) {
    char type;
    int x, y;
    Node *to_rev, *after;
    fin >> type;
    switch (type) {
      case 'I':
        fin >> x >> y;
        Insert(treap, x, y, rand());
        break;
      case 'A':
        fin >> x;
        fout << GetValue(treap, x) << "\n";
        break;
      case 'R':
        fin >> x >> y;
        after = Split(treap, y + 1);
        to_rev = Split(treap, x);
        to_rev->rev = true;
        Join(treap, to_rev);
        Join(treap, after);
        break;
      default:
        fin >> x >> y;
        for (int i = x; i <= y; ++i)
          Erase(treap, x);
    }
  }

  Print(treap);
  fout << "\n";
  return 0;
}