Cod sursa(job #2205874)

Utilizator mlc_oficialBoris Barca mlc_oficial Data 20 mai 2018 15:32:45
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.98 kb
#include <cstdio>
#include <cassert>
#include <cmath>
#include <cstring>

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <stack>
#include <queue>

#include <tuple>

#include <type_traits>

#define getchar getchar_unlocked
#define putchar putchar_unlocked

#define _rep(_1, _2, _3, _4, name, ...) name
#define rep2(i, n) rep3(i, 0, n)
#define rep3(i, a, b) rep4(i, a, b, 1)
#define rep4(i, a, b, c) for (int i = int(a); i < int(b); i += int(c))
#define rep(...) _rep(__VA_ARGS__, rep4, rep3, rep2, _)(__VA_ARGS__)

using namespace std;

using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f80 = long double;

int get_int() {
  int c, n;
  while ((c = getchar()) < '0');
  n = c - '0';
  while ((c = getchar()) >= '0') n = n * 10 + (c - '0');
  return n;
}

template <typename val_t>
class IntegralTrie {
  static_assert(is_integral<val_t>::value);
 public:
   void insert(val_t value) { insert(&root, value, W); }
   void erase(val_t value) { erase(&root, value, W); }
   bool find(val_t value) const { return find(&root, value, W); }
 private:
  static constexpr int W = sizeof(val_t) * 8;
  static constexpr int B = 3;
  
  struct Node {
    Node* son[1 << B];
    u64 active;
    Node() { active = 0; fill(son, son + (1 << B), nullptr); }
  } root;
  
  static inline int shift(val_t value, int R) {
    return (R > B ? ((value >> (R - B)) & ((1 << B) - 1)) :
                    (value & ((1 << R) - 1)));
  }
  
  void insert(Node* n, val_t value, int R) {
    const int l = shift(value, R);
    n->active |= u64(1) << l;
    if (R > B) {
      if (n->son[l] == nullptr) n->son[l] = new Node;
      insert(n->son[l], value, R - B);
    }
  }
  
  void erase(Node* n, val_t value, int R) {
    const int l = shift(value, R);
    if (~n->active >> l & 1) {
      return;
    }
    
    if (R > B) {
      erase(n->son[l], value, R - B);
      if (n->son[l]->active == 0) {
        delete n->son[l];
        n->son[l] = nullptr;
        n->active &= ~(u64(1) << l);
      }
    } else {
      n->active &= ~(u64(1) << l);
    }
  }
  
  bool find(const Node* n, val_t value, int R) const {
    const int l = shift(value, R);
    if (~n->active >> l & 1) {
      return false;
    }
    
    if (R > B) return find(n->son[l], value, R - B);
    return true;
  }
};

void solve() {
#ifdef INFOARENA
  freopen("hashuri.in", "r", stdin);
  freopen("hashuri.out", "w", stdout);
#endif

  IntegralTrie<u32> t;
  int Q = get_int();
  rep(_, Q) {
    int type = get_int(); u32 x = get_int();
    if (type == 1) {
      t.insert(x);
    } else if (type == 2) {
      t.erase(x);
    } else {
      printf("%d\n", t.find(x));
    }
  }
}

int main() {
  clock_t beg = clock();
  solve();
  clock_t end = clock();
  fprintf(stderr, "%.3f sec\n", double(end - beg) / CLOCKS_PER_SEC);
  return 0;
}