#include <bits/stdc++.h> // #pragma GCC optimize ("O3") // #pragma GCC target ("sse4") using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define pb push_back #define mp make_pair #define st first #define nd second const int MAXN = 1015; const int MAXK = 12; int MOD; LL SN[MAXN][MAXN]; // najw. po prawej, najw. po prawej a kolejny po lewej LL DP1[MAXN][MAXK], DP2[MAXN][MAXK]; LL DP1s[MAXN][MAXK], DP2s[MAXN][MAXK]; int get_result(int N, int K) { if (K >= MAXK) { return 0; } LL result = 0; REP(i,N)REP(k1,MAXK)REP(k2,MAXK) { if (max(k1, k2) != K) continue; (result += SN[N-1][i] * DP1[i+1][k1] % MOD * DP1[N-i][k2]) %= MOD; } return result; } void verify() { REP(i,MAXN) assert(get_result(i,MAXK-1) == 0); LL fact = 1; FOR(n,1,MAXN) { (fact *= n) %= MOD; LL s = 0; REP(k,MAXK) s += get_result(n, k); assert(s % MOD == fact); // printf("%d %lld\n", n, fact); } } int main() { int N, K; scanf("%d%d%d", &N, &K, &MOD); REP(i,MAXN) { SN[i][0] = SN[i][i] = 1; FOR(j,1,i) SN[i][j] = (SN[i-1][j-1] + SN[i-1][j]) % MOD; } DP1[1][0] = 1; DP2[2][1] = 1; FOR(i,1,MAXN) { REP(j,i-2) FOR(k,1,MAXK) { // int k = (k1 == k2) ? k1 + 1 : max(k1,k2); LL combs = DP2[j+2][k-1] * DP2[i-1-j][k-1] + DP2[j+2][k] * DP2s[i-1-j][k-1] + DP2s[j+2][k-1] * DP2[i-1-j][k]; LL add = combs % MOD * SN[i-3][j]; (DP2[i][k] += add) %= MOD; } REP(j,i-1) FOR(k,1,MAXK) { // int k = max(k1, k2); LL combs = DP1[j+1][k] * DP2[i-j][k] + DP1s[j+1][k-1] * DP2[i-j][k] + DP1[j+1][k] * DP2s[i-j][k-1]; LL add = combs % MOD * SN[i-2][j]; (DP1[i][k] += add) %= MOD; } DP1s[i][0] = DP1[i][0]; FOR(k,1,MAXK) DP1s[i][k] = (DP1s[i][k-1] + DP1[i][k]) % MOD; DP2s[i][0] = DP2[i][0]; FOR(k,1,MAXK) DP2s[i][k] = (DP2s[i][k-1] + DP2[i][k]) % MOD; } // verify(); printf("%d\n", get_result(N, K)); }
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 | #include <bits/stdc++.h> // #pragma GCC optimize ("O3") // #pragma GCC target ("sse4") using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define pb push_back #define mp make_pair #define st first #define nd second const int MAXN = 1015; const int MAXK = 12; int MOD; LL SN[MAXN][MAXN]; // najw. po prawej, najw. po prawej a kolejny po lewej LL DP1[MAXN][MAXK], DP2[MAXN][MAXK]; LL DP1s[MAXN][MAXK], DP2s[MAXN][MAXK]; int get_result(int N, int K) { if (K >= MAXK) { return 0; } LL result = 0; REP(i,N)REP(k1,MAXK)REP(k2,MAXK) { if (max(k1, k2) != K) continue; (result += SN[N-1][i] * DP1[i+1][k1] % MOD * DP1[N-i][k2]) %= MOD; } return result; } void verify() { REP(i,MAXN) assert(get_result(i,MAXK-1) == 0); LL fact = 1; FOR(n,1,MAXN) { (fact *= n) %= MOD; LL s = 0; REP(k,MAXK) s += get_result(n, k); assert(s % MOD == fact); // printf("%d %lld\n", n, fact); } } int main() { int N, K; scanf("%d%d%d", &N, &K, &MOD); REP(i,MAXN) { SN[i][0] = SN[i][i] = 1; FOR(j,1,i) SN[i][j] = (SN[i-1][j-1] + SN[i-1][j]) % MOD; } DP1[1][0] = 1; DP2[2][1] = 1; FOR(i,1,MAXN) { REP(j,i-2) FOR(k,1,MAXK) { // int k = (k1 == k2) ? k1 + 1 : max(k1,k2); LL combs = DP2[j+2][k-1] * DP2[i-1-j][k-1] + DP2[j+2][k] * DP2s[i-1-j][k-1] + DP2s[j+2][k-1] * DP2[i-1-j][k]; LL add = combs % MOD * SN[i-3][j]; (DP2[i][k] += add) %= MOD; } REP(j,i-1) FOR(k,1,MAXK) { // int k = max(k1, k2); LL combs = DP1[j+1][k] * DP2[i-j][k] + DP1s[j+1][k-1] * DP2[i-j][k] + DP1[j+1][k] * DP2s[i-j][k-1]; LL add = combs % MOD * SN[i-2][j]; (DP1[i][k] += add) %= MOD; } DP1s[i][0] = DP1[i][0]; FOR(k,1,MAXK) DP1s[i][k] = (DP1s[i][k-1] + DP1[i][k]) % MOD; DP2s[i][0] = DP2[i][0]; FOR(k,1,MAXK) DP2s[i][k] = (DP2s[i][k-1] + DP2[i][k]) % MOD; } // verify(); printf("%d\n", get_result(N, K)); } |