modintのライブラリを作成しました。
このライブラリの作成では、noshi91さんのブログとけんちょんさんの記事を参考にさせていただきました。
また、使用する際にはこちらのテンプレートと一緒にお使いください。
#friend関数について
本来valはpublicにするべきではないですが、競プロをする際の利便性のためにpublicにしています。もし、privateやprotectedにしたいかつクラス外からアクセスしたい場合はfriend関数を用いることでアクセス可能になります。
#入力でmodが与えられる場合
対応していません。
#C++のコード
modint.cc
template<ll mod> class modint{
public:
ll val=0;
//コンストラクタ
modint(ll x=0){while(x<0)x+=mod;val=x%mod;}
//コピーコンストラクタ
modint(const modint &r){val=r.val;}
//算術演算子
modint operator -(){return modint(-val);} //単項
modint operator +(const modint &r){return modint(*this)+=r;}
modint operator -(const modint &r){return modint(*this)-=r;}
modint operator *(const modint &r){return modint(*this)*=r;}
modint operator /(const modint &r){return modint(*this)/=r;}
//代入演算子
modint &operator +=(const modint &r){
val+=r.val;
if(val>=mod)val-=mod;
return *this;
}
modint &operator -=(const modint &r){
if(val<r.val)val+=mod;
val-=r.val;
return *this;
}
modint &operator *=(const modint &r){
val=val*r.val%mod;
return *this;
}
modint &operator /=(const modint &r){
ll a=r.val,b=mod,u=1,v=0;
while(b){
ll t=a/b;
a-=t*b;swap(a,b);
u-=t*v;swap(u,v);
}
val=val*u%mod;
if(val<0)val+=mod;
return *this;
}
//等価比較演算子
bool operator ==(const modint& r){return this->val==r.val;}
bool operator <(const modint& r){return this->val<r.val;}
bool operator !=(const modint& r){return this->val!=r.val;}
};
using mint = modint<MOD>;
//入出力ストリーム
istream &operator >>(istream &is,mint& x){//xにconst付けない
ll t;is >> t;
x=t;
return (is);
}
ostream &operator <<(ostream &os,const mint& x){
return os<<x.val;
}
//累乗
mint modpow(const mint &a,ll n){
if(n==0)return 1;
mint t=modpow(a,n/2);
t=t*t;
if(n&1)t=t*a;
return t;
}
//二項係数
vector<mint> fac,finv,inv;
//二項係数の前計算
//n:=二項係数xCyを求める時の最大のx
void COMinit(ll n) {
fac.resize(n+1);
finv.resize(n+1);
inv.resize(n+1);
fac[0]=fac[1]=1;
finv[0]=finv[1]=1;
inv[1]=1;
FOR(i,2,n){
fac[i]=fac[i-1]*mint(i);
inv[i]=-inv[MOD%i]*mint(MOD/i);
finv[i]=finv[i-1]*inv[i];
}
}
//二項係数の演算
mint COM(ll n,ll k){
if(n<k)return 0;
if(n<0 || k<0)return 0;
return fac[n]*finv[k]*finv[n-k];
}