#include <bits/stdc++.h>
using namespace std;
const int N = 1'000'001;
int fact[N], revFact[N];
vector <int> firstModRev(int n, int mod) {
vector <int> rev(n + 1, 0);
rev[1] = 1;
for (int i = 2; i <= n; i++) {
rev[i] = (-(long long) (mod / i) * rev[mod % i]) % mod;
if (rev[i] < 0) {
rev[i] += mod;
}
}
return rev;
}
void prepareFact(int mod) {
fact[0] = revFact[0] = 1;
auto rev = firstModRev(N - 1, mod);
for (int i = 1; i < N; i++) {
fact[i] = ((long long) i * fact[i - 1]) % mod;
revFact[i] = ((long long) rev[i] * revFact[i - 1]) % mod;
}
}
int generalizedCatalan(int n, int k, int mod) {
int ans = fact[k * n];
for (int i = 0; i < k; i++) {
ans = ((long long) ans * fact[i]) % mod;
ans = ((long long) ans * revFact[n + i]) % mod;
}
return ans;
}
int solveSubtask(int a, int b, int p) {
int c = generalizedCatalan(a, b, p);
return ((long long) c * c) % p;
}
map <tuple<int,int,int>,pair<int,int>> smallAnswers = {
{{3, 3, 3}, {6, 32}},
{{3, 3, 4}, {8, 504}},
{{3, 4, 4}, {9, 2016}},
{{3, 4, 5}, {11, 50820}},
{{3, 5, 5}, {12, 232320}},
{{3, 5, 6}, {14, 7651644}},
{{3, 6, 6}, {15, 38258220}},
{{4, 4, 4}, {10, 9216}},
{{4, 4, 5}, {13, 2453880}},
{{4, 4, 6}, {15, 109309200}},
{{4, 5, 5}, {14, 13741728}},
};
int main() {
ios_base::sync_with_stdio(false);
int a, b, c, p;
cin >> a >> b >> c >> p;
prepareFact(p);
if (c == a + b - 1) {
cout << a * b << ' ' << solveSubtask(a, b, p);
} else if (a == 2) {
int ans = ((long long) generalizedCatalan(b, 2, p) * generalizedCatalan(b - 1, 2, p)) % p;
cout << a * b - 1 << ' ' << ans;
} else if (smallAnswers.count({a, b, c})) {
auto [n, cnt] = smallAnswers[{a, b, c}];
cout << n << ' ' << cnt % p;
} else {
assert(false);
}
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 | #include <bits/stdc++.h> using namespace std; const int N = 1'000'001; int fact[N], revFact[N]; vector <int> firstModRev(int n, int mod) { vector <int> rev(n + 1, 0); rev[1] = 1; for (int i = 2; i <= n; i++) { rev[i] = (-(long long) (mod / i) * rev[mod % i]) % mod; if (rev[i] < 0) { rev[i] += mod; } } return rev; } void prepareFact(int mod) { fact[0] = revFact[0] = 1; auto rev = firstModRev(N - 1, mod); for (int i = 1; i < N; i++) { fact[i] = ((long long) i * fact[i - 1]) % mod; revFact[i] = ((long long) rev[i] * revFact[i - 1]) % mod; } } int generalizedCatalan(int n, int k, int mod) { int ans = fact[k * n]; for (int i = 0; i < k; i++) { ans = ((long long) ans * fact[i]) % mod; ans = ((long long) ans * revFact[n + i]) % mod; } return ans; } int solveSubtask(int a, int b, int p) { int c = generalizedCatalan(a, b, p); return ((long long) c * c) % p; } map <tuple<int,int,int>,pair<int,int>> smallAnswers = { {{3, 3, 3}, {6, 32}}, {{3, 3, 4}, {8, 504}}, {{3, 4, 4}, {9, 2016}}, {{3, 4, 5}, {11, 50820}}, {{3, 5, 5}, {12, 232320}}, {{3, 5, 6}, {14, 7651644}}, {{3, 6, 6}, {15, 38258220}}, {{4, 4, 4}, {10, 9216}}, {{4, 4, 5}, {13, 2453880}}, {{4, 4, 6}, {15, 109309200}}, {{4, 5, 5}, {14, 13741728}}, }; int main() { ios_base::sync_with_stdio(false); int a, b, c, p; cin >> a >> b >> c >> p; prepareFact(p); if (c == a + b - 1) { cout << a * b << ' ' << solveSubtask(a, b, p); } else if (a == 2) { int ans = ((long long) generalizedCatalan(b, 2, p) * generalizedCatalan(b - 1, 2, p)) % p; cout << a * b - 1 << ' ' << ans; } else if (smallAnswers.count({a, b, c})) { auto [n, cnt] = smallAnswers[{a, b, c}]; cout << n << ' ' << cnt % p; } else { assert(false); } return 0; } |
English