#include <bits/stdc++.h> using namespace std; #ifdef LOCAL template<class T, class U> ostream& operator<<(ostream& os, pair<T, U> p) { return os << "(" << p.first << ", " << p.second << ")"; } template<class C, class = typename C::value_type> typename enable_if<!is_same<C, string>::value, ostream&>::type operator<<(ostream& os, C c) { for (auto i = c.begin(); i != c.end(); i++) { os << " {"[i == c.begin()] << *i << ",}"[next(i) == c.end()]; } return os; } #define debug(x) { cerr << #x << " = " << x << endl; } #else #define debug(...) {} #endif const int N = 1003; const int K = 12; int mod; long long dp[K][N][4]; bool vis[K][N][4]; int newt[N][N]; void preprocess(int nn) { newt[0][0] = 1; for (int n = 1; n <= nn; n ++) { for (int k = 0; k <= n; k ++) { if (k == 0) newt[n][k] = 1; else newt[n][k] = (newt[n-1][k-1] + newt[n-1][k]) % mod; } } } long long policz(int n, int k, int b) { if (k < 0) return 0; if (n == 0) return 1; if (vis[k][n][b]) { return dp[k][n][b]; } //only for such ns // if (k == 0) return n == 0 || (n == 1 && bounds != 0); vis[k][n][b] = 1; if (n == 1) { //if (b || k > 0) { dp[k][n][b] = 1; //} } else { if (b & 1) { dp[k][n][b] += policz(n - 1, k, b); } else { dp[k][n][b] += policz(n - 1, k - 1, b | 1); } if (b & 2) { dp[k][n][b] += policz(n - 1, k, b); } else { dp[k][n][b] += policz(n - 1, k - 1, b | 2); } // debug(k); // debug(n); // debug(b); // debug("Part"); // debug(dp[k][n][b]); for (int poz = 2; poz < n; poz ++) { /* debug(n-1); debug(poz-1); debug(newt[n-1][poz-1]); */ if (b == 0) { long long f = (newt[n - 1][poz - 1] * policz(poz - 1, k - 1, b | 2)) % mod; dp[k][n][b] += (f * policz(n - poz, k - 1, b | 1)) % mod; dp[k][n][b] %= mod; } else if (b != 3) { long long f = (newt[n - 1][poz - 1] * policz(poz - 1, k - (b == 1), b | 2)) % mod; dp[k][n][b] += (f * policz(n - poz, k - (b == 2), b | 1)) % mod; dp[k][n][b] %= mod; } else if (b == 3) { long long f = (policz(poz-1, k-1, 3) * policz(n-poz, k, 3)) % mod; f += (policz(poz-1, k, 3) * policz(n-poz, k-1, 3)) % mod; f -= (policz(poz-1, k-1, 3) * policz(n-poz, k-1, 3)) % mod; f = (f % mod + mod) % mod; dp[k][n][b] += (newt[n-1][poz-1] * f) % mod; dp[k][n][b] %= mod; } } } dp[k][n][b] %= mod; // debug(k); // debug(n); // debug(b); // debug(dp[k][n][b]); return dp[k][n][b]; } long long wynik(int n, int k) { return policz(n, k, 0); } int main() { int nn, kk; cin >> nn >> kk >> mod; preprocess(nn); cout << (kk >= K ? 0 : (wynik(nn, kk) - wynik(nn, kk - 1) + mod)) % mod; }
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 102 103 104 105 106 107 108 109 110 111 112 113 114 | #include <bits/stdc++.h> using namespace std; #ifdef LOCAL template<class T, class U> ostream& operator<<(ostream& os, pair<T, U> p) { return os << "(" << p.first << ", " << p.second << ")"; } template<class C, class = typename C::value_type> typename enable_if<!is_same<C, string>::value, ostream&>::type operator<<(ostream& os, C c) { for (auto i = c.begin(); i != c.end(); i++) { os << " {"[i == c.begin()] << *i << ",}"[next(i) == c.end()]; } return os; } #define debug(x) { cerr << #x << " = " << x << endl; } #else #define debug(...) {} #endif const int N = 1003; const int K = 12; int mod; long long dp[K][N][4]; bool vis[K][N][4]; int newt[N][N]; void preprocess(int nn) { newt[0][0] = 1; for (int n = 1; n <= nn; n ++) { for (int k = 0; k <= n; k ++) { if (k == 0) newt[n][k] = 1; else newt[n][k] = (newt[n-1][k-1] + newt[n-1][k]) % mod; } } } long long policz(int n, int k, int b) { if (k < 0) return 0; if (n == 0) return 1; if (vis[k][n][b]) { return dp[k][n][b]; } //only for such ns // if (k == 0) return n == 0 || (n == 1 && bounds != 0); vis[k][n][b] = 1; if (n == 1) { //if (b || k > 0) { dp[k][n][b] = 1; //} } else { if (b & 1) { dp[k][n][b] += policz(n - 1, k, b); } else { dp[k][n][b] += policz(n - 1, k - 1, b | 1); } if (b & 2) { dp[k][n][b] += policz(n - 1, k, b); } else { dp[k][n][b] += policz(n - 1, k - 1, b | 2); } // debug(k); // debug(n); // debug(b); // debug("Part"); // debug(dp[k][n][b]); for (int poz = 2; poz < n; poz ++) { /* debug(n-1); debug(poz-1); debug(newt[n-1][poz-1]); */ if (b == 0) { long long f = (newt[n - 1][poz - 1] * policz(poz - 1, k - 1, b | 2)) % mod; dp[k][n][b] += (f * policz(n - poz, k - 1, b | 1)) % mod; dp[k][n][b] %= mod; } else if (b != 3) { long long f = (newt[n - 1][poz - 1] * policz(poz - 1, k - (b == 1), b | 2)) % mod; dp[k][n][b] += (f * policz(n - poz, k - (b == 2), b | 1)) % mod; dp[k][n][b] %= mod; } else if (b == 3) { long long f = (policz(poz-1, k-1, 3) * policz(n-poz, k, 3)) % mod; f += (policz(poz-1, k, 3) * policz(n-poz, k-1, 3)) % mod; f -= (policz(poz-1, k-1, 3) * policz(n-poz, k-1, 3)) % mod; f = (f % mod + mod) % mod; dp[k][n][b] += (newt[n-1][poz-1] * f) % mod; dp[k][n][b] %= mod; } } } dp[k][n][b] %= mod; // debug(k); // debug(n); // debug(b); // debug(dp[k][n][b]); return dp[k][n][b]; } long long wynik(int n, int k) { return policz(n, k, 0); } int main() { int nn, kk; cin >> nn >> kk >> mod; preprocess(nn); cout << (kk >= K ? 0 : (wynik(nn, kk) - wynik(nn, kk - 1) + mod)) % mod; } |