#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; } |
English