提交时间:2024-02-20 13:42:21

运行 ID: 26611

#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 3009; int gcd(int x, int y) { if (!y) return x; return gcd(y, x % y); } int n, P, dp[N][N], pw[N], ip[N], G[N][N], ans; bool ok[N][N]; vector<int> S[N]; int fpow(int a, int b = P - 2) { int res = 1; while (b) { if (b & 1) res = 1ll * res * a % P; a = 1ll * a * a % P, b >>= 1; } return res; } int C(int nn, int mm) { return 1ll * pw[nn] * ip[mm] % P * ip[nn - mm] % P; } int W(int m, int x, int y) { return 1ll * C(m, x * y) * G[x][y] % P; } int main() { scanf("%d%d", &n, &P); pw[0] = ip[0] = 1; for (int i = 1; i <= n; i++) { pw[i] = 1ll * pw[i - 1] * i % P; ip[i] = fpow(pw[i]); } for (int x = 0; x <= n; x++) { for (int y = 0; x * y <= n && y <= n; y++) { G[x][y] = 1ll * pw[x * y] * ip[x] % P * fpow(fpow(y, x)) % P; } } for (int i = 1; i <= n; i++) { int g = gcd(i, n - 1); S[i / g].push_back(g); } for (int i = 1; i <= n; i++) { ok[i][0] = 1; for (int k : S[i]) { for (int j = k; j <= n; j++) { ok[i][j] |= ok[i][j - k]; } } } dp[0][0] = 1; for (int i = 1; i <= n; i++) { for (int j = 0; j <= n; j++) { for (int k = 0; j + i * k <= n; k++) { if (!ok[i][k]) continue; (dp[i][j + i * k] += 1ll * dp[i - 1][j] * W(n - j, k, i) % P) %= P; } } } for (int i = 1; i <= n; i++) { (ans += 1ll * fpow(i, n - i) * dp[n][i] % P) %= P; } printf("%d\n", ans); return 0; }