intnorm(int x){ if (x < 0) { x += MOD; } if (x >= MOD) { x -= MOD; } return x; } template<class T> T binpow(T a, int b){ T res = 1; for (; b; b /= 2, a *= a) { if (b % 2) { res *= a; } } return res; }
structZ { int x; Z(int x = 0) : x(norm(x)) {} intval()const{ return x; } Z operator-() const { returnZ(norm(MOD - x)); } Z inv()const{ assert(x != 0); returnbinpow(*this, MOD - 2); } Z &operator*=(const Z &rhs) { x = 1LL * x * rhs.x % MOD; return *this; } Z &operator+=(const Z &rhs) { x = norm(x + rhs.x); return *this; } Z &operator-=(const Z &rhs) { x = norm(x - rhs.x); return *this; } Z &operator/=(const Z &rhs) { return *this *= rhs.inv(); } friend Z operator*(const Z &lhs, const Z &rhs) { Z res = lhs; res *= rhs; return res; } friend Z operator+(const Z &lhs, const Z &rhs) { Z res = lhs; res += rhs; return res; } friend Z operator-(const Z &lhs, const Z &rhs) { Z res = lhs; res -= rhs; return res; } friend Z operator/(const Z &lhs, const Z &rhs) { Z res = lhs; res /= rhs; return res; } };
structCombination { vector<Z> fac, inv;
Combination(int n) : fac(n), inv(n) { fac[0] = 1; for (int i = 1; i < n; i++) fac[i] = fac[i - 1] * i; inv[n - 1] = fac[n - 1].inv(); for (int i = n - 2; i >= 0; i--) inv[i] = inv[i + 1] * (i + 1); }
Z C(int n, int m){ if(m < 0or m > n) return0; return fac[n] * inv[m] * inv[n - m]; }
Z A(int n, int m){ if(m < 0or m > n) return0; return fac[n] * inv[n - m]; } };