#include #include #include #include #include struct dynamic_bitset { int len = 0; typedef unsigned long long ULL; std::vector val; dynamic_bitset() noexcept = default; ~dynamic_bitset() noexcept = default; dynamic_bitset(const dynamic_bitset &) noexcept = default; dynamic_bitset &operator=(const dynamic_bitset &) noexcept = default; dynamic_bitset(std::size_t n) noexcept { len = n; val.resize((n + 63) / 64); for (int i = (n + 63) / 64 - 1; i >= 0; i--) val[i] = 0; } dynamic_bitset(const std::string &str) noexcept { len = str.size(); val.resize((len + 63) / 64); for (int i = 0; i < val.size(); i++) val[i] = 0; for (int i = 0; i < len; i++) val[i / 64] |= ((1ull * (str[i] - '0')) << (i % 64)); } inline bool operator[](std::size_t n) const noexcept { return (val[n / 64] & (1ull << (n % 64))) != 0; } dynamic_bitset &set(std::size_t n, bool __val = true) noexcept { val[n / 64] &= ULL(-1) ^ (1ull << (n % 64)); val[n / 64] |= ((1ull * __val) << (n % 64)); return *this; } dynamic_bitset &push_back(bool __val) noexcept { len++; if (len % 64 == 1) val.push_back((ULL)__val); else val[(len - 1) / 64] |= ((1ull * __val) << ((len - 1) % 64)); return *this; } bool none() const noexcept { for (int i = 0; i < val.size(); i++) if (val[i] != 0) return false; return true; } bool all() const noexcept { for (int i = 0; i < val.size() - 1; i++) if (val[i] != ULL(-1)) return false; if (val[val.size() - 1] != ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1)) return false; return true; } inline std::size_t size() const noexcept { return len; } dynamic_bitset &operator|=(const dynamic_bitset &B) noexcept { int op_len = std::min(len, B.len); int op_buckets = (op_len + 63) / 64; for (int i = 0; i < op_buckets - 1; i++) val[i] |= B.val[i]; val[op_buckets - 1] |= (ULL((1ull << (op_len % 64 == 0 ? 64 : op_len % 64)) - 1ll)) & B.val[op_buckets - 1]; return *this; } dynamic_bitset &operator&=(const dynamic_bitset &B) noexcept { int op_len = std::min(len, B.len); int op_buckets = (op_len + 63) / 64; for (int i = 0; i < op_buckets - 1; i++) val[i] &= B.val[i]; val[op_buckets - 1] &= (~ULL((1ull << (op_len % 64 == 0 ? 64 : op_len % 64)) - 1ll)) | B.val[op_buckets - 1]; return *this; } dynamic_bitset &operator^=(const dynamic_bitset &B) noexcept { int op_len = std::min(len, B.len); int op_buckets = (op_len + 63) / 64; for (int i = 0; i < op_buckets - 1; i++) val[i] ^= B.val[i]; val[op_buckets - 1] ^= (ULL((1ull << (op_len % 64 == 0 ? 64 : op_len % 64)) - 1ll)) & B.val[op_buckets - 1]; return *this; } dynamic_bitset &operator<<=(std::size_t n) noexcept { int big_move = n / 64, small_move = n % 64; int ors = val.size(); val.resize((n + len + 63) / 64); int obn = val.size(); if (small_move == 0) { std::memmove(val.data() + big_move, val.data(), sizeof(ULL) * ors); std::memset(val.data(), 0, sizeof(ULL) * std::min(big_move, ors)); } else { for (int i = (n + len + 63) / 64 - 1; i >= big_move; i--) { val[i] = (((i - big_move >= 0 && i - big_move < obn ? val[i - big_move] : 0) & ULL(((1ull << (64 - small_move))) - 1)) << small_move) | ((i - big_move - 1 >= 0 ? val[i - big_move - 1] : 0) >> (64 - small_move)); } std::memset(val.data(), 0, sizeof(ULL) * std::min(big_move, ors)); } len += n; return *this; } dynamic_bitset &operator>>=(std::size_t n) noexcept { if (n > len) n = len; int big_move = n / 64, small_move = n % 64; int obn = val.size(); if (small_move == 0) { for (int i = 0; i < (len - n + 63) / 64; i++) { val[i] = (i + big_move < obn ? val[i + big_move] : 0); } } else { for (int i = 0; i < (len - n + 63) / 64; i++) { val[i] = ((i + big_move < obn ? val[i + big_move] : 0) >> small_move) | ((i + big_move + 1 < obn ? val[i + big_move + 1] : 0) << (64 - small_move)); } } len -= n; val.resize((len + 63) / 64); if (val.size() > 0) val[val.size() - 1] &= ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1ll); return *this; } dynamic_bitset &set() noexcept { if (len == 0) return *this; std::memset(val.data(), -1, sizeof(ULL) * val.size()); val[val.size() - 1] = ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1ll); return *this; } dynamic_bitset &flip() noexcept { if (len == 0) return *this; for (int i = 0; i < val.size() - 1; i++) val[i] = ~val[i]; val[val.size() - 1] ^= ULL((1ull << (len % 64 == 0 ? 64 : len % 64)) - 1ll); return *this; } dynamic_bitset &reset() noexcept { if (len == 0) return *this; std::memset(val.data(), 0, sizeof(ULL) * val.size()); return *this; } };