Cod sursa(job #2535395)

Utilizator atatomirTatomir Alex atatomir Data 31 ianuarie 2020 20:25:05
Problema Hashuri Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.68 kb
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

//#define debug(x) ;
#define debug(x) cerr << #x << " = " << x << "\n";

const int inf = 2000000000;

ostream& operator<<(ostream& cerr, vector<ll> aux) {
    cerr << "[";
    for (auto e : aux) cerr << e << ' ';
    cerr << "]";
    return cerr;
}

struct node {
  int value;
  node *left, *right, *parent;

  node(int _value) {
    value = _value;
    left = right = parent = NULL;
  }
};

void assign_dad(node* son, node* dad) {
  if (son == NULL) return;
  son->parent = dad;
  if (dad == NULL) return;
  if (dad->value < son->value) 
    dad->right = son;
  else
    dad->left = son;
}

void rot_right(node* down, node* up) {
  node* aux = down->right;
  up->left = NULL;
  assign_dad(down, up->parent);
  assign_dad(aux, up);
  assign_dad(up, down);
}

void rot_left(node* down, node* up) {
  node* aux = down->left;
  up->right = NULL;
  assign_dad(down, up->parent);
  assign_dad(aux, up);
  assign_dad(up, down);
}

void rotate(node* act) {
  node* dad = act->parent;
  if (dad == NULL) return;
  if (act->value < dad->value)
    rot_right(act, dad);
  else
    rot_left(act, dad);
}

bool trio(int a, int b, int c) {
  return (a < b && b < c) || (a > b && b > c);
}

// return root = splayed node
node* splay(node* act) {
  while (act->parent != NULL) {
    node* dad = act->parent;
    node* grand = dad->parent;

    if (grand == NULL) {
      rotate(act);
      break;
    }

    if (trio(act->value, dad->value, grand->value)) {
      rotate(dad);
      rotate(act);
    } else {
      rotate(act);
      rotate(act);
    }
  }

  return act;
}

// return searched node or a pred/succ
node* search(node* act, int v) {
  node* last = act;
  while (act != NULL) {
    last = act;
    if (act->value == v) 
      return act;

    if (v < act->value)
      act = act->left;
    else
      act = act->right;
  }
  return last;
}

// return inserted node
node* insert(node* act, int v) {
  node* dad = NULL;
  while (act != NULL) {
    dad = act;
    if (act->value == v) return act;
    if (v < act->value)
      act = act->left;
    else
      act = act->right;
  }
  act = new node(v);
  assign_dad(act, dad);
  return act;
}

int cnt = 30;
void print_tree(node* act) {
  if (act == NULL || --cnt <= 0) return;
  cerr << act << ' ' << act->value << ' ' << act->parent << ' ' << act->left << ' ' << act->right << '\n';
  print_tree(act->left);
  print_tree(act->right);
}

int n, op, x;
node* head = NULL;


int splay_query(int x) {
  node* act = search(head, x);
  if (act == NULL) return 0;
  head = splay(act);
  return act->value == x;
}

void splay_insert(int x) {
  node* act = insert(head, x);
  head = splay(act);
}

void splay_erase(int x) {
  if (splay_query(x) == false) return;

  node* left = head->left;
  node* right = head->right;
  free(head);

  if (!left && !right) {
    head = NULL;
    return;
  } 

  if (!left || !right) {
    if (!left)
      head = right;
    else
      head = left;

    head->parent = NULL;
    return;
  }

  left->parent = NULL;
  head = search(left, inf);
  head = splay(head);
  assign_dad(right, head);
}




int main()
{
    freopen("hashuri.in","r",stdin);
    freopen("hashuri.out","w",stdout);

    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
      scanf("%d%d", &op, &x);
      if (op <= 2) {
        if (op == 1) {
          splay_insert(x);
          //cerr << "done insert\n";
        } else {
          splay_erase(x);
          //cerr << "done insert\n";
        }
      } else {
        printf("%d\n", splay_query(x));
        //cerr << "done query\n";
      }
    }


    return 0;
}