Tào lao
Tào lao
void precalc() {
f[0] = 1;
for (int i = 1 ; i <= 100000 ; i++) f[i] = (f[i - 1] * i) % mod; r[100000] =
inverse(f[100000],mod);
for (int i = 99999 ; i >= 0 ; i--) r[i] = (r[i + 1] * (i + 1)) % mod;
}
long long C(long long k, long long n) {
long long numerator = f[n];
long long denominator = (r[k] * r[n - k]) % mod;
return (numerator * denominator) % mod;
}
Nhân ma trận
struct Mat {
int n, m;
vector<vector<ll>> a;
Mat() { }
Mat(int _n, int _m, ll _val = 0) {n = _n; m = _m; a.assign(n, vector<ll>(m, _val)); }
Mat(vector< vector<ll> > v) { n = v.size(); m = n ? v[0].size() : 0; a = v; }
inline void make_unit() {
assert(n == m);
for (int i = 0; i < n; i++) a[i][i] = 1;
}
inline Mat operator + (const Mat &b) {
assert(n == b.n && m == b.m);
Mat ans = Mat(n, m);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
ans.a[i][j] = (a[i][j] + b.a[i][j]) % mod;
}
}
return ans;
}
inline Mat operator - (const Mat &b) {
assert(n == b.n && m == b.m);
Mat ans = Mat(n, m);
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
ans.a[i][j] = (a[i][j] - b.a[i][j] + mod) % mod;
}
}
return ans;
}
inline Mat operator * (const Mat &b) {
assert(m == b.n);
Mat ans = Mat(n, b.m);
for(int i = 0; i < n; i++) {
for(int j = 0; j < b.m; j++) {
for(int k = 0; k < m; k++) {
ans.a[i][j] = (ans.a[i][j] + 1LL * a[i][k] * b.a[k][j] % mod) % mod;
}
}
}
return ans;
}
inline Mat pow(ll k) {
assert(n == m);
Mat ans(n, n), t = a; ans.make_unit();
while (k) {
if (k & 1) ans = ans * t;
t = t * t; k >>= 1;
}
return ans;
}
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
ios_base::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);