#include <cstdio> typedef long long LL; int p; inline int pmul(int a, int b) { return (LL(a)*b) % p; } int main() { int n, k; scanf("%d %d %d", &n, &k, &p); int** newton = new int*[n+1]; for (int i=0; i<=n; ++i) { newton[i] = new int[i+1]; newton[i][0] = 1; newton[i][i] = 1; for (int j=1; j<i; ++j) { newton[i][j] = (newton[i-1][j-1] + newton[i-1][j]) % p; } } /* printf("Newton\n"); for (int i=0; i<=n; ++i) { for (int j=0; j<=i; ++j) { printf("%d ", newton[i][j]); } printf("\n"); } */ int* fact = new int[n+1]; fact[0] = 1; for (int i=1; i<=n; ++i) { fact[i] = (LL(fact[i-1])*i) % p; } /* printf("Factorial\n"); for (int i=0; i<=n; ++i) { printf("%d ", fact[i]); } printf("\n"); */ int** two_side = new int*[k+1]; int** one_side = new int*[k+1]; int** two_side_agg = new int*[k+1]; int** one_side_agg = new int*[k+1]; for (int i=0; i<=k; ++i) { two_side[i] = new int[n+1]; one_side[i] = new int[n+1]; two_side_agg[i] = new int[n+1]; one_side_agg[i] = new int[n+1]; } two_side[0][0] = 1; two_side_agg[0][0] = 1; for (int i=1; i<=n; ++i) { two_side[0][i] = 0; two_side_agg[0][i] = 0; } for (int l=1; l<=k; ++l) { two_side[l][0] = 0; two_side_agg[l][0] = two_side_agg[l-1][0]; for (int i=1; i<=n; ++i) { if (l == 1 && i == 1) { two_side[l][i] = 1; two_side_agg[l][i] = (two_side_agg[l-1][i] + 1) % p; continue; } LL sum = 0; for (int j=0; j<i; ++j) { sum += pmul(newton[i-1][j], ((pmul(two_side[l][j], two_side_agg[l-1][i-j-1]) + pmul(two_side[l][i-j-1], two_side_agg[l-1][j])) % p + pmul(two_side[l-1][j], two_side[l-1][i-j-1])) % p); } two_side[l][i] = (int)(sum % p); two_side_agg[l][i] = (two_side_agg[l-1][i] + two_side[l][i]) % p;; } } /* printf("Two side\n"); for (int l=0; l<=k; ++l) { for (int i=0; i<=n; ++i) { printf("%d ", two_side[l][i]); } printf("\n"); } */ one_side[0][0] = 1; one_side_agg[0][0] = 1; for (int i=1; i<=n; ++i) { one_side[0][i] = 0; one_side_agg[0][i] = 0; } for (int l=1; l<=k; ++l) { one_side[l][0] = 0; one_side_agg[l][0] = one_side_agg[l-1][0]; for (int i=1; i<=n; ++i) { if (l == 1 && i == 1) { one_side[l][i] = 1; one_side_agg[l][i] = (one_side_agg[l-1][i] + 1) % p; continue; } LL sum = 0; for (int j=0; j<i; ++j) { sum += pmul(newton[i-1][j], ((pmul(one_side[l][j], two_side_agg[l-1][i-j-1]) + pmul(two_side[l-1][i-j-1], one_side_agg[l][j])) % p + p - pmul(one_side[l][j], two_side[l-1][i-j-1])) % p); } one_side[l][i] = (int)(sum % p); one_side_agg[l][i] = (one_side_agg[l-1][i] + one_side[l][i]) % p; } } /* printf("One side\n"); for (int l=0; l<=k; ++l) { for (int i=0; i<=n; ++i) { printf("%d ", one_side[l][i]); } printf("\n"); } */ LL result = 0; if (n == 1) { result = 1; } else { for (int j=0; j<n; ++j) { result += pmul(newton[n-1][j], ((pmul(one_side[k][j], one_side_agg[k-1][n-j-1]) + pmul(one_side[k][n-j-1], one_side_agg[k-1][j])) % p + pmul(one_side[k][j], one_side[k][n-j-1])) % p); } } printf("%lld\n", result % 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 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 | #include <cstdio> typedef long long LL; int p; inline int pmul(int a, int b) { return (LL(a)*b) % p; } int main() { int n, k; scanf("%d %d %d", &n, &k, &p); int** newton = new int*[n+1]; for (int i=0; i<=n; ++i) { newton[i] = new int[i+1]; newton[i][0] = 1; newton[i][i] = 1; for (int j=1; j<i; ++j) { newton[i][j] = (newton[i-1][j-1] + newton[i-1][j]) % p; } } /* printf("Newton\n"); for (int i=0; i<=n; ++i) { for (int j=0; j<=i; ++j) { printf("%d ", newton[i][j]); } printf("\n"); } */ int* fact = new int[n+1]; fact[0] = 1; for (int i=1; i<=n; ++i) { fact[i] = (LL(fact[i-1])*i) % p; } /* printf("Factorial\n"); for (int i=0; i<=n; ++i) { printf("%d ", fact[i]); } printf("\n"); */ int** two_side = new int*[k+1]; int** one_side = new int*[k+1]; int** two_side_agg = new int*[k+1]; int** one_side_agg = new int*[k+1]; for (int i=0; i<=k; ++i) { two_side[i] = new int[n+1]; one_side[i] = new int[n+1]; two_side_agg[i] = new int[n+1]; one_side_agg[i] = new int[n+1]; } two_side[0][0] = 1; two_side_agg[0][0] = 1; for (int i=1; i<=n; ++i) { two_side[0][i] = 0; two_side_agg[0][i] = 0; } for (int l=1; l<=k; ++l) { two_side[l][0] = 0; two_side_agg[l][0] = two_side_agg[l-1][0]; for (int i=1; i<=n; ++i) { if (l == 1 && i == 1) { two_side[l][i] = 1; two_side_agg[l][i] = (two_side_agg[l-1][i] + 1) % p; continue; } LL sum = 0; for (int j=0; j<i; ++j) { sum += pmul(newton[i-1][j], ((pmul(two_side[l][j], two_side_agg[l-1][i-j-1]) + pmul(two_side[l][i-j-1], two_side_agg[l-1][j])) % p + pmul(two_side[l-1][j], two_side[l-1][i-j-1])) % p); } two_side[l][i] = (int)(sum % p); two_side_agg[l][i] = (two_side_agg[l-1][i] + two_side[l][i]) % p;; } } /* printf("Two side\n"); for (int l=0; l<=k; ++l) { for (int i=0; i<=n; ++i) { printf("%d ", two_side[l][i]); } printf("\n"); } */ one_side[0][0] = 1; one_side_agg[0][0] = 1; for (int i=1; i<=n; ++i) { one_side[0][i] = 0; one_side_agg[0][i] = 0; } for (int l=1; l<=k; ++l) { one_side[l][0] = 0; one_side_agg[l][0] = one_side_agg[l-1][0]; for (int i=1; i<=n; ++i) { if (l == 1 && i == 1) { one_side[l][i] = 1; one_side_agg[l][i] = (one_side_agg[l-1][i] + 1) % p; continue; } LL sum = 0; for (int j=0; j<i; ++j) { sum += pmul(newton[i-1][j], ((pmul(one_side[l][j], two_side_agg[l-1][i-j-1]) + pmul(two_side[l-1][i-j-1], one_side_agg[l][j])) % p + p - pmul(one_side[l][j], two_side[l-1][i-j-1])) % p); } one_side[l][i] = (int)(sum % p); one_side_agg[l][i] = (one_side_agg[l-1][i] + one_side[l][i]) % p; } } /* printf("One side\n"); for (int l=0; l<=k; ++l) { for (int i=0; i<=n; ++i) { printf("%d ", one_side[l][i]); } printf("\n"); } */ LL result = 0; if (n == 1) { result = 1; } else { for (int j=0; j<n; ++j) { result += pmul(newton[n-1][j], ((pmul(one_side[k][j], one_side_agg[k-1][n-j-1]) + pmul(one_side[k][n-j-1], one_side_agg[k-1][j])) % p + pmul(one_side[k][j], one_side[k][n-j-1])) % p); } } printf("%lld\n", result % p); return 0; } |