#include <iostream> const int MAX = 1005; using LL = unsigned long long; using SLL = long long; LL modInverse(SLL a, SLL m) { SLL m0 = m; SLL y = 0, x = 1; if (m == 1) return 0; while (a > 1) { // q is quotient SLL q = a / m; SLL t = m; // m is remainder now, process same as // Euclid's algo m = a % m, a = t; t = y; // Update y and x y = x - q * y; x = t; } // Make x positive if (x < 0) x += m0; return x; } // 0 = #_# // 1 = #_ or _# int P[2][MAX][MAX]; int S[2][MAX][MAX]; int fac[MAX]; int ifac[MAX]; int inv[MAX]; int main() { std::ios_base::sync_with_stdio(false); LL N,K,p; std::cin >> N >> K >> p; fac[0] = 1; ifac[0] = 1; for (int i=1;i<=N;++i) { fac[i] = LL(fac[i-1]) * i % p; ifac[i] = modInverse(fac[i], p); inv[i] = modInverse(i, p); // std::clog << fac[i] << " / " << ifac[i] << std::endl; } P[0][1][1] = 1; P[1][1][1] = 1; S[0][1][1] = 1; S[1][1][1] = 1; P[0][0][0] = 1; P[1][0][0] = 1; S[0][0][0] = 1; S[1][0][0] = 1; for (int k=1;k<=K;++k) { S[0][0][k] = 1; S[1][0][k] = 1; S[0][1][k] = 1; S[1][1][k] = 1; } for (int k=1;k<=K;++k) { //std::clog << "* " << k << std::endl; for (int n=2;n<N;++n) { int mn = (n+1)/2; LL sum0 = 0; LL sum1 = 0; if ( k <= 11 ) for (int nn=0;nn<n;++nn) { int a = nn; int b = n - nn - 1; sum0 = ( sum0 + LL(P[0][a][k-1]) * P[0][b][k-1] + LL(P[0][a][k]) * S[0][b][k-1] + LL(S[0][a][k-1]) * P[0][b][k]) % p; // std::clog << n << ":" << k << " " << a << ":" << b << " \t " << sum << " :: " << f << std::endl; sum1 = ( sum1 + LL(S[1][a][k-1]) * P[0][b][k-1] + LL(P[1][a][k]) * S[0][b][k-1]) % p; } P[0][n][k] = sum0 * inv[n] % p; P[1][n][k] = sum1 * inv[n] % p; S[0][n][k] = (LL(S[0][n][k-1]) + P[0][n][k]) % p; S[1][n][k] = (LL(S[1][n][k-1]) + P[1][n][k]) % p; } } // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << P[1][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << S[1][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << P[0][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << S[0][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; LL result = 0; for (int n=0;n<N;++n) { int a = n; int b = N - n - 1; LL sum = LL(P[1][a][K]) * S[1][b][K] % p + LL(S[1][a][K-1]) * P[1][b][K] % p; // std::clog << N << ":" << K << " " << a << ":" << b << " \t " << sum << " :: " << f << std::endl; result = (result + sum) % p; } result = result * fac[N-1] % p; std::cout << result << std::endl; 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 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #include <iostream> const int MAX = 1005; using LL = unsigned long long; using SLL = long long; LL modInverse(SLL a, SLL m) { SLL m0 = m; SLL y = 0, x = 1; if (m == 1) return 0; while (a > 1) { // q is quotient SLL q = a / m; SLL t = m; // m is remainder now, process same as // Euclid's algo m = a % m, a = t; t = y; // Update y and x y = x - q * y; x = t; } // Make x positive if (x < 0) x += m0; return x; } // 0 = #_# // 1 = #_ or _# int P[2][MAX][MAX]; int S[2][MAX][MAX]; int fac[MAX]; int ifac[MAX]; int inv[MAX]; int main() { std::ios_base::sync_with_stdio(false); LL N,K,p; std::cin >> N >> K >> p; fac[0] = 1; ifac[0] = 1; for (int i=1;i<=N;++i) { fac[i] = LL(fac[i-1]) * i % p; ifac[i] = modInverse(fac[i], p); inv[i] = modInverse(i, p); // std::clog << fac[i] << " / " << ifac[i] << std::endl; } P[0][1][1] = 1; P[1][1][1] = 1; S[0][1][1] = 1; S[1][1][1] = 1; P[0][0][0] = 1; P[1][0][0] = 1; S[0][0][0] = 1; S[1][0][0] = 1; for (int k=1;k<=K;++k) { S[0][0][k] = 1; S[1][0][k] = 1; S[0][1][k] = 1; S[1][1][k] = 1; } for (int k=1;k<=K;++k) { //std::clog << "* " << k << std::endl; for (int n=2;n<N;++n) { int mn = (n+1)/2; LL sum0 = 0; LL sum1 = 0; if ( k <= 11 ) for (int nn=0;nn<n;++nn) { int a = nn; int b = n - nn - 1; sum0 = ( sum0 + LL(P[0][a][k-1]) * P[0][b][k-1] + LL(P[0][a][k]) * S[0][b][k-1] + LL(S[0][a][k-1]) * P[0][b][k]) % p; // std::clog << n << ":" << k << " " << a << ":" << b << " \t " << sum << " :: " << f << std::endl; sum1 = ( sum1 + LL(S[1][a][k-1]) * P[0][b][k-1] + LL(P[1][a][k]) * S[0][b][k-1]) % p; } P[0][n][k] = sum0 * inv[n] % p; P[1][n][k] = sum1 * inv[n] % p; S[0][n][k] = (LL(S[0][n][k-1]) + P[0][n][k]) % p; S[1][n][k] = (LL(S[1][n][k-1]) + P[1][n][k]) % p; } } // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << P[1][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << S[1][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << P[0][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; // for (int n=0;n<=N;++n) // { // for (int k=0;k<=K;++k) // std::clog << " \t " << S[0][n][k]; // std::clog << std::endl; // } // std::clog << std::endl; LL result = 0; for (int n=0;n<N;++n) { int a = n; int b = N - n - 1; LL sum = LL(P[1][a][K]) * S[1][b][K] % p + LL(S[1][a][K-1]) * P[1][b][K] % p; // std::clog << N << ":" << K << " " << a << ":" << b << " \t " << sum << " :: " << f << std::endl; result = (result + sum) % p; } result = result * fac[N-1] % p; std::cout << result << std::endl; return 0; } |