Cod sursa(job #1901443)

Utilizator TincaMateiTinca Matei TincaMatei Data 3 martie 2017 22:56:40
Problema Secv8 Scor 0
Compilator c Status done
Runda Arhiva de probleme Marime 3.25 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef struct _T {
  int pr, key, size;
  char l;
  _T *st, *dr;
} *T;

T make(int k) {
  T x;
  x = (T)malloc(sizeof(_T));
  x -> pr = rand() ^ rand();
  x -> key = k;
  x -> st = x -> dr = NULL;
  x -> l = 0;
  x -> size = 1;
  return x;
}

void refresh(T& x) {
  if(x != NULL) {
    x -> size = 1;
    if(x -> st != NULL) x -> size += x -> st -> size;
    if(x -> dr != NULL) x -> size += x -> dr -> size;
    if(x -> l) {
      T aux = x -> st;
      x -> st = x -> dr;
      x -> dr = aux;
      if(x -> st != NULL) x -> st -> l ^= 1;
      if(x -> dr != NULL) x -> dr -> l ^= 1;
      x -> l = false;
    }
  }
}

int size(T x) {
  if(x == NULL) return 0;
  refresh(x);
  return x -> size;
}

void split(T t, int x, T &l, T &r, int st) {
  l = r = NULL;
  if(t == NULL) return;
  int p = st + size(t -> st) + 1;
  if(p < x) {
    split(t -> dr, x, t -> dr, r, p);
    l = t;
    refresh(l);
  } else {
    split(t -> st, x, l, t -> st, st);
    r = t;
    refresh(r);
  }
}

T join(T st, T dr) {
  if(st == NULL) return dr;
  if(dr == NULL) return st;
  refresh(st);
  refresh(dr);
  if(st -> pr < dr -> pr) {
    st -> dr = join(st -> dr, dr);
    refresh(st);
    return st;
  } else {
    dr -> st = join(st, dr -> st);
    refresh(dr);
    return dr;
  }
}

void sterge(T x) {
  if(x != NULL) {
    sterge(x -> st);
    sterge(x -> dr);
    free(x);
  }
}

T add(T x, int e, int k) {
  T st, dr;
  split(x, k, st, dr, 0);
  return join(join(st, make(e)), dr);
}

T erase(T x, int i, int j) {
  T st, m, dr;
  split(x, j + 1, m, dr, 0);
  split(m, i, st, m, 0);
  sterge(m);
  return join(st, dr);
}

int acces(T x, int k) {
  T st, m, dr;
  split(x, k + 1, m, dr, 0);
  split(m, k, st, m, 0);
  int r = m -> key;
  join(join(st, m), dr);
  return r;
}

T reverse(T x, int i, int j) {
  T st, m, dr;
  split(x, j + 1, m, dr, 0);
  split(m, i, st, m, 0);
  m -> l ^= 1;
  return join(join(st, m), dr);
}

void dump(T x, FILE *fout) {
  if(x != NULL) {
    refresh(x);
    dump(x -> st, fout);
    fprintf(fout, "%d ", x -> key);
    dump(x -> dr, fout);
  }
}

int main() {
  int n, arg1, arg2;
  T x;
  srand(time(NULL));
  x = NULL;

  FILE *fin = fopen("secv8.in", "r");
  FILE *fout = fopen("secv8.out", "w");
  fscanf(fin, "%d%d", &n, &arg1);
  for(int i = 0; i < n; ++i) {
    char ch;
    ch = fgetc(fin);
    while(ch == ' ' || ch == '\n')
      ch = fgetc(fin);
    switch(ch) {
      case 'I': {
        fscanf(fin, "%d%d", &arg1, &arg2);
        x = add(x, arg2, arg1);
        break;
      }
      case 'D': {
        fscanf(fin, "%d%d", &arg1, &arg2);
        x = erase(x, arg1, arg2);
        break;
      }
      case 'A': {
        fscanf(fin, "%d", &arg1);
        fprintf(fout, "%d\n", acces(x, arg1));
        break;
      }
      case 'R': {
        fscanf(fin, "%d%d", &arg1, &arg2);
        x = reverse(x, arg1, arg2);
        break;
      }
    }
  }
  dump(x, fout);
  fclose(fin);
  fclose(fout);
  return 0;
}

//Matei cand se simte trist doreste sa se duca intr-un colt singur si sa faca prostii... cum ar fi sa bage treapuri
//autismul se manifesta prin cai misterioase
//please put me out of my misery
/*

Am I evil? Yes I am.
Am I evil? I am man.

Am I evil? Yes I fucking am.
Am I evil? I am man, yeah.

-"Am I evil?", Metallica-

*/