模板

手写 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); }
};
posted @ 2023-03-12 19:44  JerryTcl  阅读(50)  评论(0)    收藏  举报