Mathtool
Mathtool
template<u32 P>
constexpr u32 mulMod(u32 a, u32 b) {
return 1ULL * a * b % P;
}
template<u64 P>
constexpr u64 mulMod(u64 a, u64 b) {
u64 res = a * b - u64(1.L * a * b / P - 0.5L) * P;
res %= P;
return res;
}
template<typename U, U P>
requires std::unsigned_integral<U>
struct ModIntBase {
public:
constexpr ModIntBase() : x {0} {}
template<typename T>
requires std::integral<T>
constexpr ModIntBase(T x_) : x {norm(x_ % T {P})} {}
template<u32 P>
using ModInt = ModIntBase<u32, P>;
template<u64 P>
using ModInt64 = ModIntBase<u64, P>;
template<class T>
T fpow(T a, u64 b, const LL MOD) {
T res{1};
while (b) {
if (b & 1) res = (res * a) % MOD;
a = (a * a) % MOD;
b >>= 1;
}
return res;
}
void printi28(i28 x) {
string s;
while (x > 0) {
s += (x % 10 + '0');
x /= 10;
}
reverse(all(s));
W(s);
}
struct chinese_remainder_theorem {
i28 solve(vector<i28>& a, vector<i28>& M) {
i28 m = 1;
for (const i28& p : M) {
m *= p;
}
//printi28(m);
i28 res = 0;
for (int i = 0; i < si(a); ++i) {
i28 mi = m / M[i];
res = (res + a[i] * mi % m * fpow(mi, M[i] - 2, M[i])) % m;
}
return res;
}
} CRT;
void init(int m) {
// m = std::min<i64>(m, Z::getMod() - 1);
if (m <= n) return;
_fac.resize(m + 1);
_invfac.resize(m + 1);
_inv.resize(m + 1);
Z fac(int m) {
if (m > n) init(2 * m);
return _fac[m];
}
Z invfac(int m) {
if (m > n) init(2 * m);
return _invfac[m];
}
Z inv(int m) {
if (m > n) init(2 * m);
return _inv[m];
}
Z binom(int n, int m) {
if (n < m || m < 0) return 0;
return fac(n) * invfac(m) * invfac(n - m);
}
} comb;
// need to be initialized
struct PrimTable {
int n;
vector<int> pr, lp;
inline PrimTable(int n_ = 0) {
n = n_;
lp.resize(n + 1);
init();
}
vector<int> res;
while (k > 1) {
const int f = lp[k];
do {
k /= f;
} while (k % f == 0);
res.push_back(f);
}
return res;
}
};
}
using namespace mathtool;