Files
SH-Quizzes/ACMOJ-2069.hpp
2023-12-23 22:23:48 +08:00

164 lines
5.1 KiB
C++

#include <algorithm>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <vector>
struct dynamic_bitset {
int len = 0;
typedef unsigned long long ULL;
std::vector<ULL> 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;
}
};