#include <bits/stdc++.h> using namespace std; #define sim template < class c #define ris return * this #define dor > debug & operator << #define eni(x) sim > typename \ enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) { sim > struct rge { c b, e; }; sim > rge<c> range(c i, c j) { return rge<c>{i, j}; } sim > auto dud(c* x) -> decltype(cerr << *x, 0); sim > char dud(...); struct debug { #ifdef LOCAL ~debug() { cerr << endl; } eni(!=) cerr << boolalpha << i; ris; } eni(==) ris << range(begin(i), end(i)); } sim, class b dor(pair < b, c > d) { ris << "(" << d.first << ", " << d.second << ")"; } sim dor(rge<c> d) { *this << "["; for (auto it = d.b; it != d.e; ++it) *this << ", " + 2 * (it == d.b) << *it; ris << "]"; } #else sim dor(const c&) { ris; } #endif }; #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " // debug & operator << (debug & dd, P p) { dd << "(" << p.x << ", " << p.y << ")"; return dd; } int mod; void add_self(int& a, int b) { a += b; if(a >= mod) { a -= mod; } } int main() { int w, h; scanf("%d%d%d", &w, &h, &mod); // h = 10'000'000 / w; if(h == 1) { puts("1"); return 0; } vector<vector<int>> bottom(2, vector<int>(h)); vector<vector<int>> middle(2, vector<int>(h)); int cur = 0; for(int i = 0; i < h; ++i) { bottom[0][i] = 1; } for(int who = 0; who < w - 1; ++who) { for(int i = 0; i < h; ++i) { bottom[cur^1][i] = middle[cur^1][i] = 0; } // bottom -> bottom int pref = 0; for(int i = 0; i < h; ++i) { add_self(pref, bottom[cur][i]); // pref += bottom[who][i]; bottom[cur^1][i] = (bottom[cur^1][i] + (long long) pref * (h - i)) % mod; // bottom[who+1][i] += pref * (h - i); } // bottom -> middle for(int i = 0; i < h; ++i) { middle[cur^1][i] = (middle[cur^1][i] + (long long) bottom[cur][i] * (h - i)) % mod; // middle[who+1][i] += bottom[who][i] * (h - i); } // middle -> bottom pref = 0; for(int i = 0; i < h; ++i) { // pref += middle[who][i] * i; pref = (pref + (long long) middle[cur][i] * i) % mod; // bottom[who+1][i] += pref * (h - i); bottom[cur^1][i] = (bottom[cur^1][i] + (long long) pref * (h - i)) % mod; } pref = 0; for(int i = h - 1; i >= 0; --i) { // bottom[who+1][i] += pref * (i + 1); bottom[cur^1][i] = (bottom[cur^1][i] + (long long) pref * (i + 1)) % mod; // pref += middle[who][i] * (h - i); // actually, suffix pref = (pref + (long long) middle[cur][i] * (h - i)) % mod; } // middle -> middle pref = 0; for(int i = h - 1; i >= 0; --i) { // middle[who+1][i] += pref; add_self(middle[cur^1][i], pref); pref = (pref + (long long) middle[cur][i] * (h - i)) % mod; // pref += middle[who][i] * (h - i); // actually, suffix } // for(int i = 0; i < h; ++i) { // for(int j = i; j < h; ++j) { // bottom[who+1][j] += bottom[who][i] * (h - j); // } // middle[who+1][i] += bottom[who][i] * (h - i); // middle -> bottom // for(int j = 0; j < i; ++j) { // bottom[who+1][j] += middle[who][i] * (h - i) * (j + 1); // } // for(int j = i; j < h; ++j) { // bottom[who+1][j] += middle[who][i] * i * (h - j); // } // middle -> middle // for(int j = 0; j < i; ++j) { // middle[who+1][j] += middle[who][i] * (h - i) * 1; // } // } cur ^= 1; } long long answer = 0; for(int i = 0; i < h; ++i) { answer = (answer + (long long) bottom[cur][i] * (h - i) + (long long) middle[cur][i] * i % mod * (h - i)) % mod; // answer += (long long) bottom[w-1][i] * (h - i); // answer += (long long) middle[w-1][i] * i * (h - i); } printf("%lld\n", answer % mod); }
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 | #include <bits/stdc++.h> using namespace std; #define sim template < class c #define ris return * this #define dor > debug & operator << #define eni(x) sim > typename \ enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) { sim > struct rge { c b, e; }; sim > rge<c> range(c i, c j) { return rge<c>{i, j}; } sim > auto dud(c* x) -> decltype(cerr << *x, 0); sim > char dud(...); struct debug { #ifdef LOCAL ~debug() { cerr << endl; } eni(!=) cerr << boolalpha << i; ris; } eni(==) ris << range(begin(i), end(i)); } sim, class b dor(pair < b, c > d) { ris << "(" << d.first << ", " << d.second << ")"; } sim dor(rge<c> d) { *this << "["; for (auto it = d.b; it != d.e; ++it) *this << ", " + 2 * (it == d.b) << *it; ris << "]"; } #else sim dor(const c&) { ris; } #endif }; #define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] " // debug & operator << (debug & dd, P p) { dd << "(" << p.x << ", " << p.y << ")"; return dd; } int mod; void add_self(int& a, int b) { a += b; if(a >= mod) { a -= mod; } } int main() { int w, h; scanf("%d%d%d", &w, &h, &mod); // h = 10'000'000 / w; if(h == 1) { puts("1"); return 0; } vector<vector<int>> bottom(2, vector<int>(h)); vector<vector<int>> middle(2, vector<int>(h)); int cur = 0; for(int i = 0; i < h; ++i) { bottom[0][i] = 1; } for(int who = 0; who < w - 1; ++who) { for(int i = 0; i < h; ++i) { bottom[cur^1][i] = middle[cur^1][i] = 0; } // bottom -> bottom int pref = 0; for(int i = 0; i < h; ++i) { add_self(pref, bottom[cur][i]); // pref += bottom[who][i]; bottom[cur^1][i] = (bottom[cur^1][i] + (long long) pref * (h - i)) % mod; // bottom[who+1][i] += pref * (h - i); } // bottom -> middle for(int i = 0; i < h; ++i) { middle[cur^1][i] = (middle[cur^1][i] + (long long) bottom[cur][i] * (h - i)) % mod; // middle[who+1][i] += bottom[who][i] * (h - i); } // middle -> bottom pref = 0; for(int i = 0; i < h; ++i) { // pref += middle[who][i] * i; pref = (pref + (long long) middle[cur][i] * i) % mod; // bottom[who+1][i] += pref * (h - i); bottom[cur^1][i] = (bottom[cur^1][i] + (long long) pref * (h - i)) % mod; } pref = 0; for(int i = h - 1; i >= 0; --i) { // bottom[who+1][i] += pref * (i + 1); bottom[cur^1][i] = (bottom[cur^1][i] + (long long) pref * (i + 1)) % mod; // pref += middle[who][i] * (h - i); // actually, suffix pref = (pref + (long long) middle[cur][i] * (h - i)) % mod; } // middle -> middle pref = 0; for(int i = h - 1; i >= 0; --i) { // middle[who+1][i] += pref; add_self(middle[cur^1][i], pref); pref = (pref + (long long) middle[cur][i] * (h - i)) % mod; // pref += middle[who][i] * (h - i); // actually, suffix } // for(int i = 0; i < h; ++i) { // for(int j = i; j < h; ++j) { // bottom[who+1][j] += bottom[who][i] * (h - j); // } // middle[who+1][i] += bottom[who][i] * (h - i); // middle -> bottom // for(int j = 0; j < i; ++j) { // bottom[who+1][j] += middle[who][i] * (h - i) * (j + 1); // } // for(int j = i; j < h; ++j) { // bottom[who+1][j] += middle[who][i] * i * (h - j); // } // middle -> middle // for(int j = 0; j < i; ++j) { // middle[who+1][j] += middle[who][i] * (h - i) * 1; // } // } cur ^= 1; } long long answer = 0; for(int i = 0; i < h; ++i) { answer = (answer + (long long) bottom[cur][i] * (h - i) + (long long) middle[cur][i] * i % mod * (h - i)) % mod; // answer += (long long) bottom[w-1][i] * (h - i); // answer += (long long) middle[w-1][i] * i * (h - i); } printf("%lld\n", answer % mod); } |