:warning: give_us_tmp/mod_int.cpp

Code

/**
 * modint
 * 
 * 割り算やpowに関する物はO(log(mod))
 * それ以外はO(1)
 * 入出力可能
 * 
 */

template<uint mod>
struct modint{
    using M=modint;
    uint a;
    modint(ll x=0){set(x%mod+mod);}
    M& set(uint x){
        a = x<mod ? x : x-mod;
        return *this;
    }
    M operator-()const{return M()-*this;}
    M operator+(const M& x)const{return M().set(a+x.a);}
    M operator-(const M& x)const{return M().set(a-x.a+mod);}
    M operator*(const M& x)const{return M().set(ull(a)*x.a%mod);}
    M operator/(const M& x)const{return *this*x.inv();}
    M& operator+=(const M& x){return *this=*this+x;}
    M& operator-=(const M& x){return *this=*this-x;}
    M& operator*=(const M& x){return *this=*this*x;}
    M& operator/=(const M& x){return *this=*this/x;}
    bool operator==(const M& x)const{return a==x.a;}
    bool operator<(const M& x)const{return a<x.a;}
    M pow(ll n)const{
        M x=*this,r=1;
        while(n){
            if(n&1)r*=x;
            x*=x;
            n>>=1;
        }
        return r;
    }
    M inv()const{return pow(mod-2);}
    friend ostream& operator<<(ostream& os, const M& x){os<<x.a;return os;}
    friend istream& operator>>(istream& is,M& x){is>>x.a;return is;}
};

/**
 * combination
 * 
 * 前計算 :O(mx+log(mod))
 * 実行   :O(1)
 * Comb(n,k)        :n個からk個選ぶ
 * Comb::perm(n,k)  :n個から選ぶ順番を区別してk個選ぶ
 * Comb::fact(n)    :n!
 * Comb::ifact(n)   :1/n!
 * Comb::homo(n,k)  :n個から重複ありでk個選ぶ
 * 
 */

template<typename M>
struct Comb{
    static constexpr int mx=1'000'000;
    M fac[mx],ifac[mx];
    Comb(){
        fac[0]=1;
        for(int i=1;i<mx;++i){
            fac[i]=fac[i-1]*i;
        }
        ifac[mx-1]=fac[mx-1].inv();
        for(int i=mx-1;i>0;--i){
            ifac[i-1]=ifac[i]*i;
        }
    }
    M operator()(int n,int k){
        return fac[n]*ifac[k]*ifac[n-k];
    }
    M fact(int n){
        return fac[n];
    }
    M ifact(int n){
        return ifac[n];
    }
    M perm(int n,int k){
        return fac[n]*ifac[n-k];
    }
    M homo(int n,int k){
        return (*this)(n+k-1,k);
    }
};
using mint=modint<1000000007>;
Comb<mint>comb;
#line 1 "give_us_tmp/mod_int.cpp"
/**
 * modint
 * 
 * 割り算やpowに関する物はO(log(mod))
 * それ以外はO(1)
 * 入出力可能
 * 
 */

template<uint mod>
struct modint{
    using M=modint;
    uint a;
    modint(ll x=0){set(x%mod+mod);}
    M& set(uint x){
        a = x<mod ? x : x-mod;
        return *this;
    }
    M operator-()const{return M()-*this;}
    M operator+(const M& x)const{return M().set(a+x.a);}
    M operator-(const M& x)const{return M().set(a-x.a+mod);}
    M operator*(const M& x)const{return M().set(ull(a)*x.a%mod);}
    M operator/(const M& x)const{return *this*x.inv();}
    M& operator+=(const M& x){return *this=*this+x;}
    M& operator-=(const M& x){return *this=*this-x;}
    M& operator*=(const M& x){return *this=*this*x;}
    M& operator/=(const M& x){return *this=*this/x;}
    bool operator==(const M& x)const{return a==x.a;}
    bool operator<(const M& x)const{return a<x.a;}
    M pow(ll n)const{
        M x=*this,r=1;
        while(n){
            if(n&1)r*=x;
            x*=x;
            n>>=1;
        }
        return r;
    }
    M inv()const{return pow(mod-2);}
    friend ostream& operator<<(ostream& os, const M& x){os<<x.a;return os;}
    friend istream& operator>>(istream& is,M& x){is>>x.a;return is;}
};

/**
 * combination
 * 
 * 前計算 :O(mx+log(mod))
 * 実行   :O(1)
 * Comb(n,k)        :n個からk個選ぶ
 * Comb::perm(n,k)  :n個から選ぶ順番を区別してk個選ぶ
 * Comb::fact(n)    :n!
 * Comb::ifact(n)   :1/n!
 * Comb::homo(n,k)  :n個から重複ありでk個選ぶ
 * 
 */

template<typename M>
struct Comb{
    static constexpr int mx=1'000'000;
    M fac[mx],ifac[mx];
    Comb(){
        fac[0]=1;
        for(int i=1;i<mx;++i){
            fac[i]=fac[i-1]*i;
        }
        ifac[mx-1]=fac[mx-1].inv();
        for(int i=mx-1;i>0;--i){
            ifac[i-1]=ifac[i]*i;
        }
    }
    M operator()(int n,int k){
        return fac[n]*ifac[k]*ifac[n-k];
    }
    M fact(int n){
        return fac[n];
    }
    M ifact(int n){
        return ifac[n];
    }
    M perm(int n,int k){
        return fac[n]*ifac[n-k];
    }
    M homo(int n,int k){
        return (*this)(n+k-1,k);
    }
};
using mint=modint<1000000007>;
Comb<mint>comb;
Back to top page