#include <cstdio> #include <algorithm> long long int newton[1010][1010]; long long int both[1010][1010]; long long int bothsum[1010][1010]; long long int side[1010][1010]; long long int sidesum[1010][1010]; int main() { int N,K,P; scanf("%d %d %d",&N,&K,&P); //newton for (int i=0; i<=N; ++i) { newton[i][0] = newton[i][i] = 1; } for (int i=1; i<=N; ++i) { for (int j=1; j<=N-1; ++j) { newton[i][j] = newton[i-1][j-1] + newton[i-1][j]; if (newton[i][j] >= P) newton[i][j] -= P; } } //both both[0][0] = 1; both[1][1] = 1; for (int i = 0; i<=N; ++i) bothsum[0][i] = 1; for (int i = 1; i<=N; ++i) bothsum[1][i] = 1; for (int n=2; n<=N; ++n) { for (int k=1; k<=std::min(n,10); ++k) { for (int i=1; i<=n; ++i) { long long int x = 0; x += both[i-1][k]*bothsum[n-i][std::min(n-i,k-1)]; x += bothsum[i-1][std::min(i-1,k-1)]*both[n-i][k]; x += both[i-1][k-1]*both[n-i][k-1]; x %= P; both[n][k] += (newton[n-1][i-1]*x) % P; both[n][k] %= P; } bothsum[n][k] = (bothsum[n][k-1]+both[n][k]) % P; } } //side side[0][0] = 1; side[1][1] = 1; for (int i = 0; i<=N; ++i) sidesum[0][i] = 1; for (int i = 1; i<=N; ++i) sidesum[1][i] = 1; for (int n=2; n<=N; ++n) { for (int k=1; k<=std::min(n,10); ++k) { for (int i=1; i<=n; ++i) { long long int x = 0; x += both[i-1][k-1]*sidesum[n-i][std::min(n-i,k)]; if (k-2>=0) x += bothsum[i-1][std::min(i-1,k-2)]*side[n-i][k]; x %= P; side[n][k] += (newton[n-1][i-1]*x) % P; side[n][k] %= P; } sidesum[n][k] = (sidesum[n][k-1]+side[n][k]) % P; } } long long int result = 0; for (int i=1; i<=N; ++i) { long long int x = 0; x += (side[i-1][K]*sidesum[N-i][std::min(N-i,K)] + sidesum[i-1][std::min(i-1,K)]*side[N-i][K] - side[i-1][K]*side[N-i][K]) % P; result += (newton[N-1][i-1]*x) % P; result %= P; } printf("%lld\n",result); 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 | #include <cstdio> #include <algorithm> long long int newton[1010][1010]; long long int both[1010][1010]; long long int bothsum[1010][1010]; long long int side[1010][1010]; long long int sidesum[1010][1010]; int main() { int N,K,P; scanf("%d %d %d",&N,&K,&P); //newton for (int i=0; i<=N; ++i) { newton[i][0] = newton[i][i] = 1; } for (int i=1; i<=N; ++i) { for (int j=1; j<=N-1; ++j) { newton[i][j] = newton[i-1][j-1] + newton[i-1][j]; if (newton[i][j] >= P) newton[i][j] -= P; } } //both both[0][0] = 1; both[1][1] = 1; for (int i = 0; i<=N; ++i) bothsum[0][i] = 1; for (int i = 1; i<=N; ++i) bothsum[1][i] = 1; for (int n=2; n<=N; ++n) { for (int k=1; k<=std::min(n,10); ++k) { for (int i=1; i<=n; ++i) { long long int x = 0; x += both[i-1][k]*bothsum[n-i][std::min(n-i,k-1)]; x += bothsum[i-1][std::min(i-1,k-1)]*both[n-i][k]; x += both[i-1][k-1]*both[n-i][k-1]; x %= P; both[n][k] += (newton[n-1][i-1]*x) % P; both[n][k] %= P; } bothsum[n][k] = (bothsum[n][k-1]+both[n][k]) % P; } } //side side[0][0] = 1; side[1][1] = 1; for (int i = 0; i<=N; ++i) sidesum[0][i] = 1; for (int i = 1; i<=N; ++i) sidesum[1][i] = 1; for (int n=2; n<=N; ++n) { for (int k=1; k<=std::min(n,10); ++k) { for (int i=1; i<=n; ++i) { long long int x = 0; x += both[i-1][k-1]*sidesum[n-i][std::min(n-i,k)]; if (k-2>=0) x += bothsum[i-1][std::min(i-1,k-2)]*side[n-i][k]; x %= P; side[n][k] += (newton[n-1][i-1]*x) % P; side[n][k] %= P; } sidesum[n][k] = (sidesum[n][k-1]+side[n][k]) % P; } } long long int result = 0; for (int i=1; i<=N; ++i) { long long int x = 0; x += (side[i-1][K]*sidesum[N-i][std::min(N-i,K)] + sidesum[i-1][std::min(i-1,K)]*side[N-i][K] - side[i-1][K]*side[N-i][K]) % P; result += (newton[N-1][i-1]*x) % P; result %= P; } printf("%lld\n",result); return 0; } |