competitive

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

View the Project on GitHub mackerel38/competitive

:warning: math/FPSbase.hpp

Depends on

Code

#pragma once
#include "convolution"
#include <bits/stdc++.h>
using namespace std;

template <long long FPS_MOD>
struct FPS : vector<modint<FPS_MOD>> {
    using mint = modint<FPS_MOD>;
    using vector<mint>::size;
    using vector<mint>::empty;
    using vector<mint>::resize;
    using vector<mint>::operator[];
    FPS() : vector<mint>() {}
    FPS(size_t n) : vector<mint>(n) {}
    FPS(size_t n, const mint& x) : vector<mint>(n, x) {}
    FPS(const initializer_list<mint>& il) : vector<mint>(il) {}
    template<class It>
    FPS(It first, It last) : vector<mint>(first, last) {}
    FPS(const vector<mint>& v) : vector<mint>(v) {}
    FPS(vector<mint>&& v) : vector<mint>(move(v)) {}
    static vector<mint> to_vec(const FPS& f) {
        return vector<mint>(f.begin(), f.end());
    }
    static FPS from_vec(const vector<mint>& v) { return FPS(v); }
    static FPS from_vec(vector<mint>&& v) { return FPS(move(v)); }
    FPS low(int n) const {
        int take = min(n, (int)this->size());
        return FPS(this->begin(), this->begin() + take);
    }
    FPS& shrink() {
        while (!this->empty() && this->back() == mint(0)) this->pop_back();
        return *this;
    }
    FPS operator-() const {
        FPS res = *this;
        for (auto& x : res) x = -x;
        return res;
    }
    FPS& operator+=(const FPS& x) {
        if (size() < x.size()) resize(x.size());
        for (int i = 0; i < (int)x.size(); i++) (*this)[i] += x[i];
        return *this;
    }
    FPS& operator-=(const FPS& x) {
        if (size() < x.size()) resize(x.size());
        for (int i = 0; i < (int)x.size(); i++) (*this)[i] -= x[i];
        return *this;
    }
    FPS& operator*=(const FPS& x) {
        auto va = to_vec(*this);
        auto vb = to_vec(x);
        *this = from_vec(convolution(va, vb));
        return *this;
    }
    FPS operator*(const FPS& x) const { FPS t = *this; t *= x; return t; }
    FPS& operator*=(const mint& c) {
        for (auto& y : *this) y *= c;
        return *this;
    }
    FPS operator*(const mint& x) const { FPS t = *this; t *= x; return t; }
    FPS& operator/=(const mint& c) {
        mint invc = c.inv();
        for (auto& y : *this) y *= invc;
        return *this;
    }
    FPS operator/(const mint& x) const { FPS t = *this; t /= x; return t; }
    FPS operator+(const FPS& x) const { return FPS(*this) += x; }
    FPS operator-(const FPS& x) const { return FPS(*this) -= x; }
    FPS diff() const {
        if (empty()) return FPS();
        FPS g(size() - 1);
        for (int i = 1; i < (int)size(); i++) g[i - 1] = (*this)[i] * mint(i);
        return g;
    }
    FPS integ() const {
        FPS g(size() + 1);
        static vector<mint> invs = {mint(0), mint(1)};
        int n = g.size();
        for (int i=(int)invs.size(); i<n; i++) invs.push_back(-invs[FPS_MOD % i] * mint(FPS_MOD / i));
        for (int i=0; i<(int)size(); i++) g[i+1] = (*this)[i] * invs[i+1];
        return g;
    }
    FPS inv(int deg = -1) const {
        assert(!this->empty() && (*this)[0] != 0);
        int n = this->size();
        if (deg == -1) deg = n;
        FPS res; res.resize(1); res[0] = (*this)[0].inv();
        for (int m=1; m<deg; m<<=1) {
            int cut = 2 * m;
            FPS f_low = this->low(cut);
            auto vres = to_vec(res);
            auto vres2 = vres;
            auto v_f_low = to_vec(f_low);
            auto t1 = convolution(vres, vres2);
            auto t2 = convolution(t1, v_f_low);
            FPS t = from_vec(move(t2));
            t.resize(cut);
            res.resize(cut);
            for (int i=0; i<cut; i++) {
                mint ti = (i < (int)t.size() ? t[i] : mint(0));
                res[i] = res[i] * mint(2) - ti;
            }
            res = res.low(cut);
        }
        res.resize(deg);
        return res;
    }
    pair<FPS, FPS> divmod(const FPS& g) const {
        FPS f = *this;
        if (f.size() < g.size()) return {FPS{mint(0)}, f};
        int n = f.size(), m = g.size();
        FPS rf = f, rg = g;
        reverse(rf.begin(), rf.end());
        reverse(rg.begin(), rg.end());
        auto vrf = to_vec(rf);
        auto vrg = to_vec(rg);
        FPS tmp = from_vec(convolution(vrf, to_vec(rg.inv(n - m + 1))));
        FPS q = tmp.low(n - m + 1);
        reverse(q.begin(), q.end());
        FPS r = f - g * q;
        r.resize(m - 1);
        return {q, r};
    }
    FPS log(int deg = -1) const {
        assert(!this->empty() && (*this)[0] == mint(1));
        int n = this->size();
        if (deg == -1) deg = n;
        FPS f = diff();
        FPS invf = this->inv(deg);
        auto vf = to_vec(f), vinvf = to_vec(invf);
        FPS g = from_vec(convolution(vf, vinvf)).low(deg - 1).integ();
        g.resize(deg);
        return g;
    }
    FPS exp(int deg = -1) const {
        assert(!this->empty() && (*this)[0] == mint(0));
        int n = this->size();
        if (deg == -1) deg = n;
        FPS g; g.resize(1); g[0] = mint(1);
        for (int m=1; m<deg; m<<=1) {
            int cut = 2 * m;
            FPS g_log = g.log(cut);
            FPS q = this->low(cut) - g_log;
            q[0] += mint(1);
            auto vg = to_vec(g), vq = to_vec(q);
            FPS ng = from_vec(convolution(vg, vq)).low(cut);
            g = move(ng);
        }
        g.resize(deg);
        return g;
    }
    FPS pow(long long k, int n=-1) const {
        int v = 0;
        while(v < (int)this->size() && (*this)[v].val == 0) v++;
        if (v == (int)this->size()) return FPS(n, mint(0));
        if (n == -1) n = this->size();
    }
};
#line 2 "math/modint.hpp"
#include <bits/stdc++.h>
using namespace std;

template <long long modint_MOD>
struct modint {
    long long val;
    constexpr modint(long long x=0) noexcept {
        x %= modint_MOD;
        if (x < 0) x += modint_MOD;
        val = x;
    }
    explicit constexpr operator long long() const noexcept { return val; }
    template<typename Int>
    static constexpr long long adjust(Int x) noexcept {
        static_assert(std::is_integral<Int>::value, "Int must be integral");
        __int128 t = static_cast<__int128>(x);
        __int128 m = static_cast<__int128>(modint_MOD);
        t %= m;
        if (t < 0) t += m;
        return static_cast<long long>(t);
    }
    constexpr modint operator+(const modint& x) const noexcept { return modint(*this) += x; }
    constexpr modint operator-(const modint& x) const noexcept { return modint(*this) -= x; }
    constexpr modint operator*(const modint& x) const noexcept { return modint(*this) *= x; }
    constexpr modint operator/(const modint& x) const noexcept { return modint(*this) /= x; }
    constexpr modint& operator+=(const modint& x) noexcept {
        if (modint_MOD <= (val += x.val)) val -= modint_MOD;
        return *this;
    }
    constexpr modint& operator-=(const modint& x) noexcept {
        if ((val -= x.val) < 0) val += modint_MOD;
        return *this;
    }
    constexpr modint& operator*=(const modint& x) noexcept {
        __int128 t = (__int128)val * x.val;
        val = (long long)(t % modint_MOD);
        if (val < 0) val += modint_MOD;
        return *this;
    }
    constexpr modint& operator/=(modint x) noexcept {
        *this *= x.inv();
        return *this;
    }
    constexpr modint operator-() const noexcept { return modint() - *this; }
    constexpr modint& operator++() noexcept { return *this += 1; }
    constexpr modint& operator--() noexcept { return *this -= 1; }
    constexpr modint operator++(int) noexcept { modint tmp = *this; ++*this; return tmp; }
    constexpr modint operator--(int) noexcept { modint tmp = *this; --*this; return tmp; }
    constexpr bool operator==(const modint& x) const noexcept { return val == x.val; }
    constexpr bool operator!=(const modint& x) const noexcept { return val != x.val; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    constexpr modint& operator+=(Int x) noexcept {
        long long y = adjust<Int>(x);
        if (modint_MOD <= (val += y)) val -= modint_MOD;
        return *this;
    }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    constexpr modint& operator-=(Int x) noexcept {
        long long y = adjust<Int>(x);
        if ((val -= y) < 0) val += modint_MOD;
        return *this;
    }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    constexpr modint& operator*=(Int x) noexcept {
        long long y = adjust<Int>(x);
        __int128 t = (__int128)val * y;
        val = (long long)(t % modint_MOD);
        if (val < 0) val += modint_MOD;
        return *this;
    }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    constexpr modint& operator/=(Int x) noexcept {
        modint t = modint(adjust<Int>(x));
        *this /= t;
        return *this;
    }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator+(const modint& a, Int b) noexcept { modint t = a; t += b; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator+(Int a, const modint& b) noexcept { modint t = b; t += a; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator-(const modint& a, Int b) noexcept { modint t = a; t -= b; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator-(Int a, const modint& b) noexcept { modint t = modint(adjust<Int>(a)); t -= b; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator*(const modint& a, Int b) noexcept { modint t = a; t *= b; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator*(Int a, const modint& b) noexcept { modint t = b; t *= a; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator/(const modint& a, Int b) noexcept { modint t = a; t /= b; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr modint operator/(Int a, const modint& b) noexcept { modint t = modint(adjust<Int>(a)); t /= b; return t; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr bool operator==(const modint& a, Int b) noexcept { return a.val == adjust<Int>(b); }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr bool operator==(Int a, const modint& b) noexcept { return adjust<Int>(a) == b.val; }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr bool operator!=(const modint& a, Int b) noexcept { return !(a == b); }
    template<typename Int, typename = std::enable_if_t<std::is_integral<Int>::value>>
    friend constexpr bool operator!=(Int a, const modint& b) noexcept { return !(a == b); }
    friend constexpr istream& operator>> (istream& i, modint& x) { long long y; i >> y; x = modint(y); return i; }
    friend constexpr ostream& operator<< (ostream& o, const modint& x) { o << x.val; return o; }
    constexpr modint pow(long long n) const noexcept {
        if (n < 0) return inv().pow(-n);
        modint x = *this, re = 1;
        while (0 < n){
            if (n & 1) re *= x;
            x *= x;
            n >>= 1;
        }
        return re;
    }
    constexpr modint inv() const noexcept { return pow(modint_MOD - 2); }
};

template <long long modint_MOD>
struct factor {
    vector<modint<modint_MOD>> fac, ifac;
    factor(int n) : fac(n+1), ifac(n+1) {
        fac[0] = 1;
        for (int i=1; i<=n; i++) fac[i] = fac[i-1] * i;
        ifac[n] = fac[n].inv();
        for (int i=n; 1<=i; i--) ifac[i-1] = ifac[i] * i;
    }
    modint<modint_MOD> P(int n, int r) const noexcept { return (r<0 || n<r) ? 0 : fac[n] * ifac[n-r]; }
    modint<modint_MOD> C(int n, int r) const noexcept { return (r<0 || n<r) ? 0 : P(n, r) * ifac[r]; }
    modint<modint_MOD> H(int n, int r) const noexcept { return (n==0 && r==0) ? 1 : C(n+r-1, r); }
};
#line 4 "math/NTT.hpp"
using namespace std;

template <long long NTT_MOD>
void NTT(vector<modint<NTT_MOD>>& a, bool inv=false, int g_=3) {
    modint<NTT_MOD> g = g_;
    int n = (int)a.size();
    for (int i=1, j=0; i<n; i++) {
        int bit = n >> 1;
        for (; j&bit; bit>>=1) j ^= bit;
        j ^= bit;
        if (i < j) swap(a[i], a[j]);
    }
    for (int len=2; len<=n; len<<=1) {
        modint<NTT_MOD> wlen = g.pow((NTT_MOD - 1) / len);
        if (inv) wlen = wlen.inv();
        for (int i=0; i<n; i+=len) {
            modint<NTT_MOD> w = 1;
            for (int j=0; j<len/2; j++) {
                modint<NTT_MOD> u = a[i+j];
                modint<NTT_MOD> v = a[i+j+len/2]*w;
                a[i+j] = u + v;
                a[i+j+len/2] = u - v;
                w *= wlen;
            }
        }
    }
    if (inv) {
        modint<NTT_MOD> inv_n = modint<NTT_MOD>(n).inv();
        for (auto& x : a) x *= inv_n;
    }
}
#line 4 "math/convolution.hpp"
using namespace std;

template<long long convolution_MOD>
vector<modint<convolution_MOD>> convolution(vector<modint<convolution_MOD>> a,vector<modint<convolution_MOD>> b){
    int n = 1;
    int s = (int)(a.size()+b.size()-1);
    while (n < s) n<<=1;
    a.resize(n);
    b.resize(n);
    NTT(a);
    NTT(b);
    for (int i=0; i<n; i++) a[i] *= b[i];
    NTT(a,true);
    a.resize(s);
    return a;
}
#line 4 "math/FPSbase.hpp"
using namespace std;

template <long long FPS_MOD>
struct FPS : vector<modint<FPS_MOD>> {
    using mint = modint<FPS_MOD>;
    using vector<mint>::size;
    using vector<mint>::empty;
    using vector<mint>::resize;
    using vector<mint>::operator[];
    FPS() : vector<mint>() {}
    FPS(size_t n) : vector<mint>(n) {}
    FPS(size_t n, const mint& x) : vector<mint>(n, x) {}
    FPS(const initializer_list<mint>& il) : vector<mint>(il) {}
    template<class It>
    FPS(It first, It last) : vector<mint>(first, last) {}
    FPS(const vector<mint>& v) : vector<mint>(v) {}
    FPS(vector<mint>&& v) : vector<mint>(move(v)) {}
    static vector<mint> to_vec(const FPS& f) {
        return vector<mint>(f.begin(), f.end());
    }
    static FPS from_vec(const vector<mint>& v) { return FPS(v); }
    static FPS from_vec(vector<mint>&& v) { return FPS(move(v)); }
    FPS low(int n) const {
        int take = min(n, (int)this->size());
        return FPS(this->begin(), this->begin() + take);
    }
    FPS& shrink() {
        while (!this->empty() && this->back() == mint(0)) this->pop_back();
        return *this;
    }
    FPS operator-() const {
        FPS res = *this;
        for (auto& x : res) x = -x;
        return res;
    }
    FPS& operator+=(const FPS& x) {
        if (size() < x.size()) resize(x.size());
        for (int i = 0; i < (int)x.size(); i++) (*this)[i] += x[i];
        return *this;
    }
    FPS& operator-=(const FPS& x) {
        if (size() < x.size()) resize(x.size());
        for (int i = 0; i < (int)x.size(); i++) (*this)[i] -= x[i];
        return *this;
    }
    FPS& operator*=(const FPS& x) {
        auto va = to_vec(*this);
        auto vb = to_vec(x);
        *this = from_vec(convolution(va, vb));
        return *this;
    }
    FPS operator*(const FPS& x) const { FPS t = *this; t *= x; return t; }
    FPS& operator*=(const mint& c) {
        for (auto& y : *this) y *= c;
        return *this;
    }
    FPS operator*(const mint& x) const { FPS t = *this; t *= x; return t; }
    FPS& operator/=(const mint& c) {
        mint invc = c.inv();
        for (auto& y : *this) y *= invc;
        return *this;
    }
    FPS operator/(const mint& x) const { FPS t = *this; t /= x; return t; }
    FPS operator+(const FPS& x) const { return FPS(*this) += x; }
    FPS operator-(const FPS& x) const { return FPS(*this) -= x; }
    FPS diff() const {
        if (empty()) return FPS();
        FPS g(size() - 1);
        for (int i = 1; i < (int)size(); i++) g[i - 1] = (*this)[i] * mint(i);
        return g;
    }
    FPS integ() const {
        FPS g(size() + 1);
        static vector<mint> invs = {mint(0), mint(1)};
        int n = g.size();
        for (int i=(int)invs.size(); i<n; i++) invs.push_back(-invs[FPS_MOD % i] * mint(FPS_MOD / i));
        for (int i=0; i<(int)size(); i++) g[i+1] = (*this)[i] * invs[i+1];
        return g;
    }
    FPS inv(int deg = -1) const {
        assert(!this->empty() && (*this)[0] != 0);
        int n = this->size();
        if (deg == -1) deg = n;
        FPS res; res.resize(1); res[0] = (*this)[0].inv();
        for (int m=1; m<deg; m<<=1) {
            int cut = 2 * m;
            FPS f_low = this->low(cut);
            auto vres = to_vec(res);
            auto vres2 = vres;
            auto v_f_low = to_vec(f_low);
            auto t1 = convolution(vres, vres2);
            auto t2 = convolution(t1, v_f_low);
            FPS t = from_vec(move(t2));
            t.resize(cut);
            res.resize(cut);
            for (int i=0; i<cut; i++) {
                mint ti = (i < (int)t.size() ? t[i] : mint(0));
                res[i] = res[i] * mint(2) - ti;
            }
            res = res.low(cut);
        }
        res.resize(deg);
        return res;
    }
    pair<FPS, FPS> divmod(const FPS& g) const {
        FPS f = *this;
        if (f.size() < g.size()) return {FPS{mint(0)}, f};
        int n = f.size(), m = g.size();
        FPS rf = f, rg = g;
        reverse(rf.begin(), rf.end());
        reverse(rg.begin(), rg.end());
        auto vrf = to_vec(rf);
        auto vrg = to_vec(rg);
        FPS tmp = from_vec(convolution(vrf, to_vec(rg.inv(n - m + 1))));
        FPS q = tmp.low(n - m + 1);
        reverse(q.begin(), q.end());
        FPS r = f - g * q;
        r.resize(m - 1);
        return {q, r};
    }
    FPS log(int deg = -1) const {
        assert(!this->empty() && (*this)[0] == mint(1));
        int n = this->size();
        if (deg == -1) deg = n;
        FPS f = diff();
        FPS invf = this->inv(deg);
        auto vf = to_vec(f), vinvf = to_vec(invf);
        FPS g = from_vec(convolution(vf, vinvf)).low(deg - 1).integ();
        g.resize(deg);
        return g;
    }
    FPS exp(int deg = -1) const {
        assert(!this->empty() && (*this)[0] == mint(0));
        int n = this->size();
        if (deg == -1) deg = n;
        FPS g; g.resize(1); g[0] = mint(1);
        for (int m=1; m<deg; m<<=1) {
            int cut = 2 * m;
            FPS g_log = g.log(cut);
            FPS q = this->low(cut) - g_log;
            q[0] += mint(1);
            auto vg = to_vec(g), vq = to_vec(q);
            FPS ng = from_vec(convolution(vg, vq)).low(cut);
            g = move(ng);
        }
        g.resize(deg);
        return g;
    }
    FPS pow(long long k, int n=-1) const {
        int v = 0;
        while(v < (int)this->size() && (*this)[v].val == 0) v++;
        if (v == (int)this->size()) return FPS(n, mint(0));
        if (n == -1) n = this->size();
    }
};
Back to top page