Cod sursa(job #1783964)

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

using namespace std;

const int BUFF_SIZE = (1 << 17);

FILE *fin, *fout;
int bp = BUFF_SIZE - 1;
char buff[BUFF_SIZE];

inline void next_char() {
  if (++bp == BUFF_SIZE) {
    fread(buff, 1, BUFF_SIZE, fin);
    bp = 0;
  }
}

inline char get_char() {
  while (isalnum(buff[bp]) == 0)
    next_char();
  char ch = buff[bp];
  next_char();
  return ch;
}

inline int get_num() {
  int num = 0;
  while (isdigit(buff[bp]) == 0)
    next_char();
  while (isdigit(buff[bp])) {
    num = num * 10 + buff[bp] - '0';
    next_char();
  }
  return num;
}

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);
}

void print_treap(TreapNode *node) {
  if (node == nil)
    return;
  propag_rev(node);
  print_treap(node->left_son);
  fprintf(fout, "%d ", 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;
    fin = fopen("secv8.in", "r");
    n = get_num(); rev = get_num();
    root = nil;
    fout = fopen("secv8.out", "w");
    for (i = 0; i < n; ++i) {
      type = get_char(); x = get_num();
      switch (type) {
        case 'I': y = get_num();
                  insert_node(root, x, y, (rand() & INF));
                  break;
        case 'A': fprintf(fout, "%d\n", get_value(root, x));
                  break;
        case 'R': y = get_num();
                  aux2 = split(root, y + 1);
                  aux1 = split(root, x);
                  aux1->rev = true;
                  join(root, aux1);
                  join(root, aux2);
                  break;
        case 'D': y = get_num();
                  aux2 = split(root, y + 1);
                  aux1 = split(root, x);
                  delete_treap(aux1);
                  join(root, aux2);
                  break;
      }
    }
    fclose(fin);
    print_treap(root);
    fprintf(fout, "\n");
    fclose(fout);
    return 0;
}