Cod sursa(job #1998025)

Utilizator TincaMateiTinca Matei TincaMatei Data 6 iulie 2017 12:23:00
Problema Secv8 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.69 kb
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <ctype.h>

const int MAX_NODURI = 250000;
const int BUFF = 4096;

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

int curs = BUFF - 1;
char buftea[BUFF];

char getch(FILE *fin) {
  ++curs;
  if(curs == BUFF) {
    curs = 0;
    fread(buftea, 1, BUFF, fin);
  }
  return buftea[curs];
}

int getnr(FILE *fin) {
  int nr = 0;
  char ch = getch(fin);
  bool neg = false;
  while(ch != '-' && !isdigit(ch))
    ch = getch(fin);
  if(ch == '-') {
    neg = true;
    getch(fin);
  }
  while(isdigit(ch)) {
    nr = nr * 10 + ch - '0';
    ch = getch(fin);
  }
  if(neg)
    return -nr;
  return nr;
}

int top;
int memory[MAX_NODURI];

void init() {
  while(top < MAX_NODURI) {
    memory[top] = MAX_NODURI - top - 1;
    ++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() {
  srand(time(NULL));
  int n, bit, a1, a2;
  char ch;
  int id = -1;
  init();
  FILE *fin = fopen("secv8.in", "r");
  FILE *fout = fopen("secv8.out", "w");
  n = getnr(fin);
  bit = getnr(fin);
  for(int i = 0; i < n; ++i) {
    ch = getch(fin);
    while(ch == ' ' || ch == '\n')
      ch = getch(fin);
      if(ch == 'I') {
        a1 = getnr(fin);
        a2 = getnr(fin);
        id = addT(id, a1, a2);
      } else if(ch == 'D') {
        a1 = getnr(fin);
        a2 = getnr(fin);
        id = eraseT(id, a1, a2);
      } else if(ch == 'R') {
        a1 = getnr(fin);
        a2 = getnr(fin);
        id = reverseT(id, a1, a2);
      } else if(ch == 'A') {
        a1 = getnr(fin);
        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;
}