Cod sursa(job #1580053)

Utilizator bciobanuBogdan Ciobanu bciobanu Data 25 ianuarie 2016 13:59:11
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <fstream>
#include <random>
#include <ctime>
#include <cassert>

using namespace std;

const int MAX_LEVEL = 20;
const int BUFFSIZE = (int) 5e6;
const int INF = (int) 2e9 + 1;

int sl[BUFFSIZE];
int update[MAX_LEVEL + 1];
int buffPtr, level;

static inline
int getLevel(void) {
  static mt19937 gen(time(0));
  int x = gen();

  if (x < 0) {
    x = -x;
  }
  x |= (1 << MAX_LEVEL);
  return 32 - __builtin_clz(x & -x);
}

static inline
int slFind(const int &X) {
  int pos = 0;
  for (int l = level; l; l--) {
    while (sl[sl[pos + l]] < X) {
      pos = sl[pos + l];
    }
    update[l] = pos;
  }
  return sl[pos + 1];
}

static inline
void slInsert(const int &X) {
  int pos = slFind(X);

  if (sl[pos] != X) {
    int newLevel = getLevel();

    if (newLevel > level) {
      level = newLevel;
    }

    sl[buffPtr] = X;
    for (int i = 1; i <= newLevel; i++) {
      sl[buffPtr + i] = sl[update[i] + i];
      sl[update[i] + i] = buffPtr;
    }
    buffPtr += newLevel + 1;
    assert(buffPtr < BUFFSIZE);
  }
}

static inline
void slErase(const int &X) {
  int pos = slFind(X);

  if (sl[pos] == X) {
    int i = 1;
    while (i <= MAX_LEVEL && sl[update[i] + i] == pos) {
       sl[update[i] + i] = sl[pos + i];
       i++;
    }
  }
}

int main() {
  ifstream in("hashuri.in");
  ofstream out("hashuri.out");
  in.tie(0);
  ios_base::sync_with_stdio(false);
  int Q;
  int opType, x;

  sl[0] = -INF;
  sl[MAX_LEVEL + 1] = INF;
  for (int i = 1; i <= MAX_LEVEL; i++)
    sl[i] = MAX_LEVEL + 1;
  buffPtr = MAX_LEVEL + 2;
  level = 1;

  in >> Q;
  while (Q--) {
    in >> opType >> x;
    if (opType == 1) {
      slInsert(x);
    } else if (opType == 2) {
      slErase(x);
    } else {
      out.put('0' + (sl[slFind(x)] == x));
      out.put('\n');
    }
  }
  in.close();
  out.close();
  return 0;
}