Cod sursa(job #1997969)

Utilizator TincaMateiTinca Matei TincaMatei Data 5 iulie 2017 23:26:34
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>

const int MAX_NODURI = 250000;

int key[MAX_NODURI], prio[MAX_NODURI], left[MAX_NODURI], right[MAX_NODURI], sizet[MAX_NODURI];
bool rev[MAX_NODURI];

int top;
int memory[MAX_NODURI];

void init() {
  while(top < MAX_NODURI) {
    memory[top] = top;
    ++top;
  }
}

int newt(int k) {
  int id = memory[--top];
  key[id] = k;
  prio[id] = rand() ^ rand();
  left[id] = -1;
  right[id] = -1;
  sizet[id] = 1;
  return id;
}

void deletet(int id) {
  if(id != -1) {
    memory[top++] = id;
    deletet(left[id]);
    deletet(right[id]);
  }
}

void prop(int id) {
  if(rev[id]) {
    rev[id] = false;
    int aux = left[id];
    left[id] = right[id];
    right[id] = aux;
    if(left[id] != -1) rev[left[id]] ^= 1;
    if(right[id] != -1) rev[right[id]] ^= 1;
  }
}

void recalc(int id) {
  sizet[id] = 1;
  prop(id);
  if(left[id] != -1) sizet[id] += sizet[left[id]];
  if(right[id] != -1) sizet[id] += sizet[right[id]];
}

int getsize(int id) {
  if(id == -1) return 0;
  recalc(id);
  return sizet[id];
}

int join(int id1, int id2) {
  if(id1 == -1) return id2;
  if(id2 == -1) return id1;
  recalc(id1);
  recalc(id2);
  if(prio[id1] < prio[id2]) {
    right[id1] = join(right[id1], id2);
    recalc(id1);
    return id1;
  } else {
    left[id2] = join(id1, left[id2]);
    recalc(id2);
    return id2;
  }
}

void split(int id, int p, int &l, int &r, int extra) {
  l = r = -1;
  if(id == -1) return;
  recalc(id);
  int poz = 1 + extra + getsize(left[id]);
  if(poz < p) {
    split(right[id], p, right[id], r, poz);
    l = id;
    recalc(l);
  } else {
    split(left[id], p, l, left[id], extra);
    r = id;
    recalc(r);
  }
}

int addT(int id, int k, int e) {
  int l, r;
  split(id, k, l, r, 0);
  return join(join(l, newt(e)), r);
}

int eraseT(int x, int p1, int p2) {
  int l, m, r;
  split(x, p2 + 1, m, r, 0);
  split(m, p1, l, m, 0);
  deletet(m);
  return join(l, r);
}

int reverseT(int x, int p1, int p2) {
  int l, m, r;
  split(x, p2 + 1, m, r, 0);
  split(m, p1, l, m, 0);
  rev[m] = true;
  return join(join(l, m), r);
}

int accesT(int x, int k, int extra) {
  recalc(x);
  int poz = 1 + extra + getsize(left[x]);
  if(poz == k)
    return key[x];
  else if(poz < k)
    return accesT(right[x], k, poz);
  else
    return accesT(left[x], k, extra);
}

int main() {
  int n, bit, a1, a2;
  char ch;
  int id = -1;
  init();
  FILE *fin = fopen("secv8.in", "r");
  FILE *fout = fopen("secv8.out", "w");
  fscanf(fin, "%d%d", &n, &bit);
  for(int i = 0; i < n; ++i) {
    ch = fgetc(fin);
    while(ch == ' ' || ch == '\n')
      ch = fgetc(fin);if(ch == 'I') {
      fscanf(fin, "%d%d", &a1, &a2);
      id = addT(id, a1, a2);
    } else if(ch == 'D') {
      fscanf(fin, "%d%d", &a1, &a2);
      id = eraseT(id, a1, a2);
    } else if(ch == 'R') {
      fscanf(fin, "%d%d", &a1, &a2);
      id = reverseT(id, a1, a2);
    } else if(ch == 'A') {
      fscanf(fin, "%d", &a1);
      fprintf(fout, "%d\n", accesT(id, a1, 0));
    }
  }

  n = getsize(id);
  for(int i = 1; i <= n; ++i)
    fprintf(fout, "%d ", accesT(id, i, 0));
  fclose(fin);
  fclose(fout);
  return 0;
}