Nyaan's Library

This documentation is automatically generated by online-judge-tools/verification-helper

View on GitHub

:warning: 動的bitset
(data-structure/dynamic-bitset.hpp)

Code

#pragma once

#pragma GCC optimize("O3,unroll-loops")

struct BitSet {
  using u64 = unsigned long long;
  vector<u64> a;
  size_t N;

  static u64 maskbit(size_t pos) { return 1uLL << pos; }

  struct ref {
    u64 *p;
    size_t pos;
    ref(BitSet &b, size_t _pos) {
      p = b.a.data() + _pos / 64;
      pos = _pos % 64;
    }
    operator bool() const { return (*p & maskbit(pos)) != 0; }
    bool operator~() const { return (*p & maskbit(pos)) == 0; }
    ref &flip() {
      *p ^= maskbit(pos);
      return *this;
    }
    ref &operator=(bool x) {
      if (x) {
        *p |= maskbit(pos);
      } else {
        *p &= ~maskbit(pos);
      }
      return *this;
    }
    ref &operator=(const ref &r) { return *this = bool(r); }
  };

  BitSet(size_t _N) : a((_N + 63) / 64, 0), N(_N) {}

  ref operator[](size_t pos) { return ref(*this, pos); }
  bool operator[](size_t pos) const {
    return (a[pos / 64] & maskbit(pos % 64)) != 0;
  }
  bool test(size_t pos) const { return (a[pos / 64] & maskbit(pos % 64)) != 0; }
  void set(size_t pos) { a[pos / 64] |= maskbit(pos % 64); }
  void reset(size_t pos) { a[pos / 64] &= ~maskbit(pos % 64); }
  void flip(size_t pos) { a[pos / 64] ^= maskbit(pos % 64); }
  size_t size() const { return N; }

  __attribute__((optimize("O3,unroll-loops"))) BitSet &operator^=(
      const BitSet &r) {
    assert(a.size() == r.a.size());
    for (size_t i = 0; i < a.size(); i++) a[i] ^= r.a[i];
    return *this;
  }

  __attribute__((optimize("O3,unroll-loops"))) int _Find_next(size_t i) const {
    ++i;
    if (i >= N) return N;
    size_t M = i / 64;
    u64 buf = a[M];
    buf &= ~u64(0) << (i % 64);
    if (buf != 0) return M * 64 + __builtin_ctzll(buf);
    for (; ++M < a.size();) {
      if (a[M] != 0) return M * 64 + __builtin_ctzll(a[M]);
    }
    return N;
  }
  int _Find_first() const { return _Find_next(-1); }

  __attribute__((optimize("O3,unroll-loops"))) int _Find_prev(size_t i) const {
    if (i == 0) return -1;
    if ((*this)[--i] == true) return i;
    size_t M = i / 64;
    u64 buf = a[M];
    buf &= maskbit(i % 64) - 1;
    if (buf != 0) return M * 64 + 63 - __builtin_clzll(buf);
    while (M--) {
      if (a[M] != 0) return M * 64 + 63 - __builtin_clzll(a[M]);
    }
    return -1;
  }
  int _Find_last() const { return _Find_prev(N); }
};

/**
 * @brief 動的bitset
 */
#line 2 "data-structure/dynamic-bitset.hpp"

#pragma GCC optimize("O3,unroll-loops")

struct BitSet {
  using u64 = unsigned long long;
  vector<u64> a;
  size_t N;

  static u64 maskbit(size_t pos) { return 1uLL << pos; }

  struct ref {
    u64 *p;
    size_t pos;
    ref(BitSet &b, size_t _pos) {
      p = b.a.data() + _pos / 64;
      pos = _pos % 64;
    }
    operator bool() const { return (*p & maskbit(pos)) != 0; }
    bool operator~() const { return (*p & maskbit(pos)) == 0; }
    ref &flip() {
      *p ^= maskbit(pos);
      return *this;
    }
    ref &operator=(bool x) {
      if (x) {
        *p |= maskbit(pos);
      } else {
        *p &= ~maskbit(pos);
      }
      return *this;
    }
    ref &operator=(const ref &r) { return *this = bool(r); }
  };

  BitSet(size_t _N) : a((_N + 63) / 64, 0), N(_N) {}

  ref operator[](size_t pos) { return ref(*this, pos); }
  bool operator[](size_t pos) const {
    return (a[pos / 64] & maskbit(pos % 64)) != 0;
  }
  bool test(size_t pos) const { return (a[pos / 64] & maskbit(pos % 64)) != 0; }
  void set(size_t pos) { a[pos / 64] |= maskbit(pos % 64); }
  void reset(size_t pos) { a[pos / 64] &= ~maskbit(pos % 64); }
  void flip(size_t pos) { a[pos / 64] ^= maskbit(pos % 64); }
  size_t size() const { return N; }

  __attribute__((optimize("O3,unroll-loops"))) BitSet &operator^=(
      const BitSet &r) {
    assert(a.size() == r.a.size());
    for (size_t i = 0; i < a.size(); i++) a[i] ^= r.a[i];
    return *this;
  }

  __attribute__((optimize("O3,unroll-loops"))) int _Find_next(size_t i) const {
    ++i;
    if (i >= N) return N;
    size_t M = i / 64;
    u64 buf = a[M];
    buf &= ~u64(0) << (i % 64);
    if (buf != 0) return M * 64 + __builtin_ctzll(buf);
    for (; ++M < a.size();) {
      if (a[M] != 0) return M * 64 + __builtin_ctzll(a[M]);
    }
    return N;
  }
  int _Find_first() const { return _Find_next(-1); }

  __attribute__((optimize("O3,unroll-loops"))) int _Find_prev(size_t i) const {
    if (i == 0) return -1;
    if ((*this)[--i] == true) return i;
    size_t M = i / 64;
    u64 buf = a[M];
    buf &= maskbit(i % 64) - 1;
    if (buf != 0) return M * 64 + 63 - __builtin_clzll(buf);
    while (M--) {
      if (a[M] != 0) return M * 64 + 63 - __builtin_clzll(a[M]);
    }
    return -1;
  }
  int _Find_last() const { return _Find_prev(N); }
};

/**
 * @brief 動的bitset
 */
Back to top page