#include <bits/stdc++.h> using namespace std; const int N = 1002; const int K = 12; const long long LIMIT = 6LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL; int binom[N][N]; long long tmp[K][3]; int dp[N][K][3]; int add(int x, int y, int p) { x += y; if (x >= p) { x -= p; } return x; } void pre(int p) { for (int i = 0; i < N; i++) { binom[i][0] = 1; } for (int i = 1; i < N; i++) for (int j = 1; j <= i; j++) { binom[i][j] = add(binom[i-1][j], binom[i-1][j-1], p); } for (int b = 0; b < 3; b++) { dp[0][0][b] = 1; dp[1][0][b] = b == 0; dp[1][1][b] = b != 0; } for (int n = 2; n < N; n++) { for (int n1 = 0; n1 < n; n1++) { int n2 = n - 1 - n1; int ways = binom[n-1][n1]; for (int k = 0; k < K; k++) for (int b = 0; b < 3; b++) { tmp[k][b] = 0; } for (int k1 = 0; k1 < K; k1++) for (int bLeft = 0; bLeft < 2; bLeft++) { if (!dp[n1][k1][bLeft + 1]) { continue; } for (int k2 = 0; k2 < K; k2++) for (int bRight = bLeft; bRight < 2; bRight++) { if (!dp[n2][k2][bRight + 1]) { continue; } int k; if (bLeft && bRight) { k = max(k1, k2) + (k1 == k2); } else { k = max(k1 + bLeft, k2 + bRight); } tmp[k][bLeft + bRight] += (long long) dp[n1][k1][bLeft + 1] * dp[n2][k2][bRight + 1]; if (tmp[k][bLeft + bRight] >= LIMIT) { tmp[k][bLeft + bRight] %= p; } } } for (int k = 0; k < K; k++) for (int b = 0; b < 3; b++) { if (tmp[k][b] >= p) { tmp[k][b] %= p; } dp[n][k][b] = (dp[n][k][b] + (long long) ways * tmp[k][b]) % p; } } } } int solve(int n, int k, int p) { if (k >= K) { return 0; } return dp[n][k][0]; } int main() { ios_base::sync_with_stdio(0); int n, k, p; cin >> n >> k >> p; pre(p); cout << solve(n, k, p); return 0; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #include <bits/stdc++.h> using namespace std; const int N = 1002; const int K = 12; const long long LIMIT = 6LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL * 1000LL; int binom[N][N]; long long tmp[K][3]; int dp[N][K][3]; int add(int x, int y, int p) { x += y; if (x >= p) { x -= p; } return x; } void pre(int p) { for (int i = 0; i < N; i++) { binom[i][0] = 1; } for (int i = 1; i < N; i++) for (int j = 1; j <= i; j++) { binom[i][j] = add(binom[i-1][j], binom[i-1][j-1], p); } for (int b = 0; b < 3; b++) { dp[0][0][b] = 1; dp[1][0][b] = b == 0; dp[1][1][b] = b != 0; } for (int n = 2; n < N; n++) { for (int n1 = 0; n1 < n; n1++) { int n2 = n - 1 - n1; int ways = binom[n-1][n1]; for (int k = 0; k < K; k++) for (int b = 0; b < 3; b++) { tmp[k][b] = 0; } for (int k1 = 0; k1 < K; k1++) for (int bLeft = 0; bLeft < 2; bLeft++) { if (!dp[n1][k1][bLeft + 1]) { continue; } for (int k2 = 0; k2 < K; k2++) for (int bRight = bLeft; bRight < 2; bRight++) { if (!dp[n2][k2][bRight + 1]) { continue; } int k; if (bLeft && bRight) { k = max(k1, k2) + (k1 == k2); } else { k = max(k1 + bLeft, k2 + bRight); } tmp[k][bLeft + bRight] += (long long) dp[n1][k1][bLeft + 1] * dp[n2][k2][bRight + 1]; if (tmp[k][bLeft + bRight] >= LIMIT) { tmp[k][bLeft + bRight] %= p; } } } for (int k = 0; k < K; k++) for (int b = 0; b < 3; b++) { if (tmp[k][b] >= p) { tmp[k][b] %= p; } dp[n][k][b] = (dp[n][k][b] + (long long) ways * tmp[k][b]) % p; } } } } int solve(int n, int k, int p) { if (k >= K) { return 0; } return dp[n][k][0]; } int main() { ios_base::sync_with_stdio(0); int n, k, p; cin >> n >> k >> p; pre(p); cout << solve(n, k, p); return 0; } |