模板
手写 bitset:
template<int _N> struct Bitset {
const static int W = 64, B = 6;
typedef unsigned long long Word;
const static int N = _N, S = N / W + (N % W != 0);
Word data[S];
inline int GetW(const int pos) const { return pos / W; }
inline int GetB(const int pos) const { return pos % W; }
inline Word Mask(const int pos) const { return 1ull << GetB(pos); }
inline void set(const int pos) { data[GetW(pos)] |= Mask(pos); }
inline void reset(const int pos) { data[GetW(pos)] &= ~Mask(pos); }
inline void set(const int pos, const int v) { v ? set(pos) : reset(pos); }
inline int get(const int pos) const { return (data[GetW(pos)] >> GetB(pos)) & 1; }
inline void andeq(const Bitset &o) { for(int i = 0; i < S; ++i) data[i] &= o.data[i]; }
inline void oreq(const Bitset &o) { for(int i = 0; i < S; ++i) data[i] |= o.data[i]; }
inline void lshift() {
for(int i = S - 1; i > 0; --i)
data[i] = (data[i] << 1) | (data[i - 1] >> (W - 1));
data[0] <<= 1;
}
};
取模:
const int Mod = 998244353;
inline int Add(int x, int y) { return (x += y) >= Mod ? x - Mod : x; }
inline void Inc(int &x, int y) { if((x += y) >= Mod) x -= Mod; }
inline int Sub(int x, int y) { return (x -= y) < 0 ? x + Mod : x; }
inline void Dec(int &x, int y) { if((x -= y) < 0) x += Mod; }
inline int Mul(int x, int y) { return (long long)x * y % Mod; }
inline int Sqr(int x) { return Mul(x, x); }
inline int Cub(int x) { return Mul(Mul(x, x), x); }
inline int Pow(int x, int y) {
int r = 1;
for(; y; y >>= 1, x = Mul(x, x))
if(y & 1) r = Mul(r, x);
return r;
}
inline int Inv(int x) { return Pow(x, Mod - 2); }
组合数:
const int Mod = 998244353;
inline int Add(int x, int y) { return (x += y) >= Mod ? x - Mod : x; }
inline int Mul(int x, int y) { return (long long)x * y % Mod; }
inline int Inv(int x) {
int y = Mod - 2, r = 1;
for(; y; y >>= 1, x = Mul(x, x))
if(y & 1) r = Mul(r, x);
return r;
}
vector<int> fac, ifac, iv;
void InitComb(const int n) {
iv.resize(n + 1), fac.resize(n + 1), fac[0] = 1;
for(int i = 1; i <= n; ++i) fac[i] = Mul(fac[i - 1], i);
ifac.resize(n + 1), ifac[n] = Inv(fac[n]);
for(int i = n; i >= 1; --i) ifac[i - 1] = Mul(ifac[i], i);
for(int i = 1; i <= n; ++i) iv[i] = Mul(fac[i - 1], ifac[i]);
}
int C(int n, int m) { return Mul(fac[n], Mul(ifac[m], ifac[n - m])); }
// int C(int n, int m) { return (m < 0 || m > n) ? 0 : Mul(fac[n], Mul(ifac[m], ifac[n - m])); }
压位 Trie
using u64 = unsigned long long;
constexpr inline int lwbit(u64 x) { return __builtin_ctzll(x); }
constexpr inline int hibit(u64 x) { return 63 ^ __builtin_clzll(x); }
struct LwMask { u64 base[64]; u64 operator[] (int x) const { return base[x]; }
constexpr LwMask() : base() { for(int i = 0; i < 64; ++i) base[i] = (1ull << i) - 1; } };
struct HiMask { u64 base[64]; constexpr u64 operator[] (int x) const { return base[x]; }
constexpr HiMask() : base() { for(int i = 0; i < 64; ++i) base[i] = ~1ull << i; } };
constexpr LwMask lwMask = LwMask(); constexpr HiMask hiMask = HiMask();
struct BitwiseTrie {
vector<vector<u64>> trie; u64 root;
BitwiseTrie(int sz = 0) : trie(4), root(0) { resize(sz); }
inline void resize(int sz) {
trie[0].resize((sz >> 6) + 1), trie[1].resize((sz >> 12) + 1);
trie[2].resize((sz >> 18) + 1), trie[3].resize((sz >> 24) + 1);
}
inline void insert(int x0) {
const int x1 = x0 >> 6, x2 = x0 >> 12, x3 = x0 >> 18, x4 = x0 >> 24;
trie[0][x1] |= (1ull << (x0 & 63)), trie[1][x2] |= (1ull << (x1 & 63));
trie[2][x3] |= (1ull << (x2 & 63)), trie[3][x4] |= (1ull << (x3 & 63)), root |= (1ull << x4);
}
inline void erase(int x0) {
const int x1 = x0 >> 6, x2 = x0 >> 12, x3 = x0 >> 18, x4 = x0 >> 24;
if(trie[0][x1] &= ~(1ull << (x0 & 63))) return;
if(trie[1][x2] &= ~(1ull << (x1 & 63))) return;
if(trie[2][x3] &= ~(1ull << (x2 & 63))) return;
if(trie[3][x4] &= ~(1ull << (x3 & 63))) return; root &= ~(1ull << x4);
}
inline int pre(int x0) const {
const int x1 = x0 >> 6, x2 = x0 >> 12, x3 = x0 >> 18, x4 = x0 >> 24; u64 v; int r;
if((v = trie[0][x1] & lwMask[x0 & 63])) return (x0 & ~63) | hibit(v);
if((v = trie[1][x2] & lwMask[x1 & 63])) { r = (x1 & ~63) | hibit(v); goto L1; }
if((v = trie[2][x3] & lwMask[x2 & 63])) { r = (x2 & ~63) | hibit(v); goto L2; }
if((v = trie[3][x4] & lwMask[x3 & 63])) { r = (x3 & ~63) | hibit(v); goto L3; }
if(!(v = root & lwMask[x4])) return 0; r = hibit(v);
r = r << 6 | hibit(trie[3][r]); L3: r = r << 6 | hibit(trie[2][r]);
L2: r = r << 6 | hibit(trie[1][r]); L1: r = r << 6 | hibit(trie[0][r]); return r;
}
inline int nxt(int x0) const {
const int x1 = x0 >> 6, x2 = x0 >> 12, x3 = x0 >> 18, x4 = x0 >> 24; u64 v; int r;
if((v = trie[0][x1] & hiMask[x0 & 63])) return (x0 & ~63) | lwbit(v);
if((v = trie[1][x2] & hiMask[x1 & 63])) { r = (x1 & ~63) | lwbit(v); goto L1; }
if((v = trie[2][x3] & hiMask[x2 & 63])) { r = (x2 & ~63) | lwbit(v); goto L2; }
if((v = trie[3][x4] & hiMask[x3 & 63])) { r = (x3 & ~63) | lwbit(v); goto L3; }
if(!(v = root & hiMask[x4])) return 0; r = lwbit(v);
r = r << 6 | lwbit(trie[3][r]); L3: r = r << 6 | lwbit(trie[2][r]);
L2: r = r << 6 | lwbit(trie[1][r]); L1: r = r << 6 | lwbit(trie[0][r]); return r;
}
};
巨大 modint
template <unsigned Mod> struct Z {
using uint = unsigned; uint val;
using u64 = unsigned long long;
using u128 = __uint128_t;
static constexpr uint mod = Mod;
static constexpr uint shrink(uint x) { return x >= mod ? x - mod : x; }
static constexpr uint dilate(uint x) { return x >> 31 ? x + mod : x; }
constexpr Z() = default; constexpr Z(uint x) : val(x % mod) {}
constexpr Z(u64 x) : val((uint)(x % mod)) {}
template <typename T> constexpr Z(T x) : val(dilate((uint)(x % (int)mod))) {}
static constexpr Z _(uint x) { return { x }; }
constexpr Z operator - () const { return _(val ? mod - val : 0); }
constexpr Z operator + (const Z &o) const { return _(shrink(val + o.val)); }
constexpr Z operator - (const Z &o) const { return _(dilate(val - o.val)); }
constexpr Z operator * (const Z &o) const { return Z((u64)val * o.val); }
template <typename T> constexpr Z pow(T y, Z r = 1) const
{ Z x = *this; { for(; y; y >>= 1, x *= x) if(y & 1) r *= x; } return r; }
constexpr Z operator / (const Z &o) const { return o.pow(mod - 2, val); }
constexpr Z operator ~ () const { return pow(mod - 2); }
template <typename T> constexpr Z operator ^ (T y) const { return pow(y); }
constexpr Z div2() const { return _((val + (val & 1 ? mod : 0)) >> 1); }
constexpr Z sqr() const { return *this * *this; }
constexpr bool operator == (const Z &o) const { return val == o.val; }
constexpr bool operator != (const Z &o) const { return val != o.val; }
Z &operator += (const Z &o) { return *this = *this + o; }
Z &operator -= (const Z &o) { return *this = *this - o; }
Z &operator *= (const Z &o) { return *this = *this * o; }
Z &operator /= (const Z &o) { return *this = *this / o; }
template <typename T> Z &operator ^= (T y) { return *this = pow(y); }
constexpr Z _neg() const { return _(mod - val); }
constexpr Z _add(const Z &o) const { return _(val + o.val); }
static constexpr u64 _mul(const Z &p, const Z &q) { return (u64)p.val * q.val; }
static constexpr u64 _sum() { return 0; }
template <typename ...Args> static constexpr u64 _sum
(const Z &p, const Args &... args) { return p.val + _sum(args...); }
template <int N> static constexpr u64 _mul_sum() { return 0; }
template <int N> static constexpr u64 _mul_sum(const Z &p) { return p.val; }
template <int N, typename ...Args> static constexpr u64 _mul_sum
(const Z &p, const Z &q, const Args &... args)
{ return N ? _mul(p, q) + _mul_sum<max(N - 1, 0)>(args...) : _sum(p, q, args...); }
template <typename ...Args> static constexpr
Z sum(const Args&... args) { return Z(_sum(args...)); }
template <int N, typename ...Args> static constexpr
Z mul_sum(const Args &... args) { return Z(_mul_sum<N>(args...)); }
template <typename Iter> static constexpr Z sum(Iter s, size_t n)
{ u64 res = 0; { while(n--) res += (s++)->val; } return Z(res); }
template <typename Iter> static constexpr Z sum(Iter s, Iter t)
{ u64 res = 0; { while(s != t) res += (s++)->val; } return Z(res); }
template <typename Iter> static constexpr Z dot(Iter s, Iter t, size_t n)
{ u128 res = 0; { while(n--) res += (u64)(s++)->val * (t++)->val; } return Z(res); }
template <typename Iter> static constexpr Z conv(Iter s, Iter t, size_t n)
{ u128 res = 0; { for(t += n; n--; ) res += (u64)(s++)->val * (--t)->val; } return Z(res); }
};

浙公网安备 33010602011771号