Cod sursa(job #1783949)

Utilizator cella.florescuCella Florescu cella.florescu Data 19 octombrie 2016 17:05:35
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 4.46 kb
#include <bits/stdc++.h>

using namespace std;

const int INF = 1073741823;

struct TreapNode {
  TreapNode(int v, int p, int w, TreapNode *ls, TreapNode *rs) : value(v), priority(p), weight(w), rev(false), left_son(ls), right_son(rs) {}
  int value, priority, weight;
  bool rev;
  TreapNode *left_son, *right_son;
};

TreapNode *aux1, *aux2, *root, *nil = new TreapNode(0, -5318008, 0, nullptr, nullptr);

inline void get_weight(TreapNode *node) {
  node->weight = node->left_son->weight + node->right_son->weight + 1;
}

inline void propag_rev(TreapNode *node) {
  if (node->rev) {
    node->rev = false;
    swap(node->left_son, node->right_son);
    node->left_son->rev ^= 1;
    node->right_son->rev ^= 1;
  }
}

inline void rot_right(TreapNode *&node) {
  TreapNode *aux = node->left_son;
  node->left_son = aux->right_son;
  aux->right_son = node;
  get_weight(node);
  node = aux;
  get_weight(node);
}

inline void rot_left(TreapNode *&node) {
  TreapNode *aux = node->right_son;
  node->right_son = aux->left_son;
  aux->left_son = node;
  get_weight(node);
  node = aux;
  get_weight(node);
}

int get_value(TreapNode *node, int pos) {
  propag_rev(node);
  if (pos == node->left_son->weight + 1)
    return node->value;
  if (pos <= node->left_son->weight)
    return get_value(node->left_son, pos);
  return get_value(node->right_son, pos - node->left_son->weight - 1);
}

ofstream fout("secv8.out");

void print_treap(TreapNode *node) {
  if (node == nil)
    return;
  propag_rev(node);
  print_treap(node->left_son);
  fout << node->value << " ";
  print_treap(node->right_son);
}

void insert_node(TreapNode *&node, int pos, int v, int p) {
  if (node == nil) {
    node = new TreapNode(v, p, 1, nil, nil);
    return;
  }
  propag_rev(node);
  if (pos <= node->left_son->weight + 1)
    insert_node(node->left_son, pos, v, p);
  else
    insert_node(node->right_son, pos - node->left_son->weight - 1, v, p);
  if (node->left_son->priority > node->priority)
    rot_right(node);
  else if (node->right_son->priority > node->priority)
    rot_left(node);
  get_weight(node);
}

void erase_node(TreapNode *&node, int pos) {
  propag_rev(node);
  if (pos != node->left_son->weight + 1) {
    if (pos <= node->left_son->weight)
      erase_node(node->left_son, pos);
    else
      erase_node(node->right_son, pos - node->left_son->weight - 1);
    get_weight(node);
    return;
  }
  if (node->left_son == nil && node->right_son == nil) {
    delete node;
    node = nil;
    return;
  }
  if (node->left_son->priority > node->right_son->priority) {
    propag_rev(node->left_son);
    rot_right(node);
    erase_node(node->right_son, node->right_son->left_son->weight + 1);
  } else {
    propag_rev(node->right_son);
    rot_left(node);
    erase_node(node->left_son, node->left_son->left_son->weight + 1);
  }
  get_weight(node);
}

TreapNode* split(TreapNode *&node, int pos) {
  insert_node(node, pos, 5318008, INF + 1);
  TreapNode *left = node->left_son, *right = node->right_son;
  delete node;
  node = left;
  return right;
}

void join(TreapNode *&cos, TreapNode *tel) {
  cos = new TreapNode(5318008, INF + 1, cos->weight + tel->weight + 1, cos, tel);
  erase_node(cos, cos->left_son->weight + 1);
}

void delete_treap(TreapNode *&node) {
  if (node->left_son != nil)
    delete_treap(node->left_son);
  if (node->right_son != nil)
    delete_treap(node->right_son);
  delete node;
  node = nil;
}

int main()
{
    srand(time(0));
    int n, rev, i, x, y;
    char type;
    ifstream fin("secv8.in");
    fin >> n >> rev;
    root = nil;
    for (i = 0; i < n; ++i) {
      fin >> type >> x;
      switch (type) {
        case 'I': fin >> y;
                  insert_node(root, x, y, (rand() & INF));
                  break;
        case 'A': fout << get_value(root, x) << '\n';
                  break;
        case 'R': fin >> y;
                  aux2 = split(root, y + 1);
                  aux1 = split(root, x);
                  aux1->rev = true;
                  join(root, aux1);
                  join(root, aux2);
                  break;
        case 'D': fin >> y;
                  aux2 = split(root, y + 1);
                  aux1 = split(root, x);
                  delete_treap(aux1);
                  join(root, aux2);
                  break;
      }
    }
    print_treap(root);
    fout << '\n';
    fin.close();
    fout.close();
    return 0;
}