Cod sursa(job #2393212)

Utilizator stoianmihailStoian Mihail stoianmihail Data 31 martie 2019 04:14:46
Problema Hashuri Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.69 kb
#include <cstdio>
#include <cstdlib>

struct AVL {
  int key;
  int height;
  struct AVL *left, *right;
} *NIL;

typedef struct AVL AVL;

const int MAX_BUFF = 16 * 1024;
int buffer = MAX_BUFF;
AVL** memoryBuffer;

AVL* init() {
  NIL = (AVL*)malloc(sizeof(AVL));
  NIL -> key = 0;
  NIL -> height = 0;
  NIL -> left = NIL -> right = NULL;
  return NIL;
}

int MAX(int X, int Y) {
  return X > Y ? X : Y;
}

void calculateHeight(AVL* tree) {
  tree -> height = 1 + MAX(tree -> left -> height, tree -> right -> height);
}

AVL* rotateRight(AVL* tree) {
  AVL* save = tree -> right;
  tree -> right = tree -> right -> left;
  save -> left = tree;
  calculateHeight(tree);
  calculateHeight(save);
  return save;
}

AVL* rotateLeft(AVL* tree) {
  AVL* save = tree -> left;
  tree -> left = tree -> left -> right;
  save -> right = tree;
  calculateHeight(tree);
  calculateHeight(save);
  return save;
}

AVL* balance(AVL* tree) {
  calculateHeight(tree);

  // Need right rotation.
  if ((tree -> right -> height - tree -> left -> height) > 1) {
    if (tree -> right -> left -> height >
        tree -> right -> right -> height)
      tree -> right = rotateLeft(tree -> right);
    tree = rotateRight(tree);
  } else if ((tree -> left -> height - tree -> right -> height) > 1) {
    if (tree -> left -> right -> height >
        tree -> left -> left -> height)
      tree -> left = rotateRight(tree -> left);
    tree = rotateLeft(tree);
  }
  return tree;
}

bool find(AVL* tree, const int key) {
  if (tree == NIL)
    return false;
  if (tree -> key == key)
    return true;
  if (key < tree -> key)
    return find(tree -> left, key);
  return find(tree -> right, key);
}

AVL* allocMemory() {
  if (buffer == MAX_BUFF) {
    buffer = 0;
    memoryBuffer = (AVL**)calloc(MAX_BUFF, sizeof(AVL*));
    for (int i = 0; i < MAX_BUFF; i++) {
      memoryBuffer[i] = (AVL*)malloc(sizeof(AVL));
    }
  }
  return memoryBuffer[buffer++];
}

AVL* insert(AVL* tree, const int key) {
  if (tree == NIL) {
    tree = allocMemory();
    //fprintf(stderr, "%x\n", *tree);
    tree -> key = key;
    tree -> height = 1;
    tree -> left = tree -> right = NIL;
    //fprintf(stderr, "raus");
    return tree;
  }
  if (tree -> key == key)
    return tree;
  if (key < tree -> key)
    tree -> left = insert(tree -> left, key);
  else
    tree -> right = insert(tree -> right, key);
  return balance(tree);
}

AVL* erase(AVL* tree, const int key) {
  if (tree == NIL)
    return tree;
  if (tree -> key == key) {
    if ((tree -> left == NIL) || (tree -> right == NIL)) {
      AVL* ret = (tree -> left == NIL) ? tree -> right : tree -> left;
      free(tree);
      return ret;
    } else {
      // Both aren't NIL.
      AVL* next;
      for (next = tree -> right; next -> left != NIL; next = next -> left);
      tree -> key = next -> key;
      tree -> right = erase(tree -> right, next -> key);
      return balance(tree);
    }
  } else if (key < tree -> key) {
    tree -> left = erase(tree -> left, key);
  } else {
    tree -> right = erase(tree -> right, key);
  }
  return balance(tree);
}

int main(void) {
  FILE *f = fopen("hashuri.in", "r");
  freopen("hashuri.out", "w", stdout);

  AVL* root = init();

  int N, task, x;
  fscanf(f, "%d", &N);
  //memoryBuffer = (AVL**)calloc(N, sizeof(AVL*));
  while (N--) {
    fscanf(f, "%d %d\n", &task, &x);
    //fprintf(stderr, "%d -> %d mit %d\n", N, task, x);
    switch (task) {
      case 1:
        root = insert(root, x); break;
      case 2:
        root = erase(root, x); break;
      case 3:
        fprintf(stdout, "%d\n", find(root, x)); break;
    }
  }
  return 0;
}