Cod sursa(job #1901454)

Utilizator TincaMateiTinca Matei TincaMatei Data 3 martie 2017 23:13:15
Problema Secv8 Scor 25
Compilator c Status done
Runda Arhiva de probleme Marime 3.34 kb
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

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

T make(int k) {
  T x;
  x = (T)malloc(sizeof(struct _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 = 0;
    }
  }
}

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-

*/