Espionage
Mier_Samuelle · · 题解
:::info[Statement]{open}
给定
1s,
:::
逐层考虑。对于第
现在要将这
然后就可以 dp 了。定义
:::success[Code]{open}
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const int MAXN = 310;
ll fac[MAXN], inv[MAXN], n, m, d;
struct Matrix{
int x, y;
ll a[MAXN][MAXN];
Matrix operator * (const Matrix &b) const{
Matrix tmp = {};
tmp.x = x;
tmp.y = b.y;
for (int i = 1; i <= x; i++){
for (int j = 1; j <= b.y; j++){
for (int k = 1; k <= b.x; k++){
tmp.a[i][j] = (tmp.a[i][j] + b.a[k][j] * a[i][k] % MOD) % MOD;
}
}
}
return tmp;
}
}st, base;
Matrix qpow(Matrix x, ll y){
Matrix res = x;
y--;
while (y){
if (y & 1){
res = res * x;
}
x = x * x;
y >>= 1;
}
return res;
}
ll qpow(ll x, ll y){
ll res = 1;
while (y){
if (y & 1){
res = res * x % MOD;
}
x = x * x % MOD;
y >>= 1;
}
return res;
}
ll cb(ll x, ll y){
if (x < y){
return 0;
}
return fac[x] * inv[y] % MOD * inv[x - y] % MOD;
}
ll A(ll x, ll y){
if (x == 0 && y == 0){
return 1;
}
if (y == 0){
return 0;
}
return fac[x] * inv[y] % MOD * cb(x - 1, y - 1) % MOD;
}
ll M(ll x, ll y){
ll res = 0;
for (int i = 0; i <= min(n - 2 * y, x); i++){
res = (res + ((i & 1 ? -1 : 1) * cb(n - 2 * y, i) % MOD + MOD) % MOD * A(n - y - i, x - i) % MOD) % MOD;
}
return res;
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
d = n / 2;
fac[0] = inv[0] = 1;
for (int i = 1; i <= n; i++){
fac[i] = fac[i - 1] * i % MOD;
inv[i] = qpow(fac[i], MOD - 2);
}
base.x = base.y = d + 1;
for (int i = 1; i <= d + 1; i++){
for (int j = 1; j <= d + 1; j++){
base.a[i][j] = M(j - 1, i - 1);
}
}
st.x = 1;
st.y = d + 1;
st.a[1][1] = 1;
Matrix res = st * qpow(base, m - 1);
ll ans = 0;
for (int i = 1; i <= d + 1; i++){
ans = (ans + res.a[1][i] * fac[n - i] % MOD) % MOD;
}
cout << ans << "\n";
return 0;
}
:::