Cod sursa(job #1577182)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 23 ianuarie 2016 12:04:46
Problema Hashuri Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <cstdio>
#include <algorithm>

using namespace std;

const int MAX_N = 1000000;
const int BUFFSIZE = 130000;

struct Treap {
  int key;
  int priority;
  int st, dr;
};

Treap T[1 + MAX_N];
int v[MAX_N];

static inline
char GetChar() {
  static char buff[BUFFSIZE];
  static int pos = BUFFSIZE;

  if (pos == BUFFSIZE) {
    fread(buff, 1, BUFFSIZE, stdin);
    pos = 0;
  }
  return buff[pos++];
}

static inline
int ReadInt() {
  register unsigned q = 0;
  char c;

  do {
    c = GetChar();
  } while (c < 33);
  do {
    q = (q << 1) + (q << 3) + (c - '0');
    c = GetChar();
  } while (c > 32);
  return q;
}

void TreapSplit(int node, const int key, int &st, int &dr) {
  if (!node) {
    st = dr = 0;
  } else if (key < T[node].key) {
    TreapSplit(T[node].st, key, st, T[node].st);
    dr = node;
  } else if (key > T[node].key) {
    TreapSplit(T[node].dr, key, T[node].dr, dr);
    st = node;
  }
}

void TreapInsert(int &node, int &insertPtr) {
  if (!node) {
    node = insertPtr;
  } else if (T[insertPtr].priority > T[node].priority) {
    TreapSplit(node, T[insertPtr].key, T[insertPtr].st, T[insertPtr].dr);
    node = insertPtr;
  } else {
    if (T[insertPtr].key < T[node].key)
      TreapInsert(T[node].st, insertPtr);
    else if (T[insertPtr].key > T[node].key)
      TreapInsert(T[node].dr, insertPtr);
    else
      insertPtr--;
  }
}

void TreapMerge(int &node, const int st, const int dr) {
  if (!st || !dr)
    node = st ^ dr;
  else if (T[st].priority > T[dr].priority) {
    TreapMerge(T[st].dr, T[st].dr, dr);
    node = st;
  } else {
    TreapMerge(T[dr].st, st, T[dr].st);
    node = dr;
  }
}

void TreapErase(int &node, const int key) {
  if (!node) {
    return;
  }
  if (T[node].key == key)
    TreapMerge(node, T[node].st, T[node].dr);
  else if (key < T[node].key)
    TreapErase(T[node].st, key);
  else
    TreapErase(T[node].dr, key);
}

bool TreapFind(int node, const int key) {
  T[0].key = key;
  while (T[node].key != key) {
    if (T[node].key > key) {
      node = T[node].st;
    } else {
      node = T[node].dr;
    }
  }
  T[0].key = 0;
  return node;
}

void DUMP(int node) {
  if (!node) {
    return;
  }
  DUMP(T[node].st);
  printf("%d ", T[node].key);
  DUMP(T[node].dr);
}

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

  int N;
  int TrRoot, TrPtr;
  int opType, x;

  N = ReadInt();

  for (int i = 0; i < N; i++)
    v[i] = i;
  random_shuffle(v, v + N);

  for (int i = 1; i <= N; i++)
    T[i].priority = v[i-1];

  TrRoot = 0;
  TrPtr = 0;
  while (N--) {
    opType = ReadInt();
    x = ReadInt();
    if (opType == 1) {
      T[++TrPtr].key = x;
      TreapInsert(TrRoot, TrPtr);
    } else if (opType == 2) {
      TreapErase(TrRoot, x);
    } else {
      putchar('0' + TreapFind(TrRoot, x));
      putchar('\n');
    }
  }
  fclose(stdin); fclose(stdout);
  return 0;
}