#include <cassert> #include <cstdint> #include <cstring> #include <algorithm> #include <iostream> #include <memory> #include <string> #include <vector> typedef int16_t i16; typedef int32_t i32; typedef int64_t i64; typedef uint8_t u8; class Tab { i32 _rows; i32 _columns; std::unique_ptr<i32[]> _data; public: Tab(i32 rows, i32 columns) : _rows(rows), _columns(columns), _data(new i32[rows * columns]) {} i32 * operator[](i32 row) { return row * _columns + _data.get(); } i32 & operator()(i32 row, i32 column) { return _data[row * _columns + column]; } }; i32 prime; inline i32 normalize(i64 a) { return a % prime; } inline i32 add(i32 a, i32 b) { assert(0 <= a); assert(a < prime); assert(0 <= b); assert(b < prime); auto x = a + b; return (x > prime) ? x - prime : x; } inline i32 sub(i32 a, i32 b) { assert(0 <= a); assert(a < prime); assert(0 <= b); assert(b < prime); auto x = a - b; return (x < 0) ? x + prime : x; } int main() { i32 n, m; std::cin >> n >> m >> prime; Tab Q(n, m+1); auto Q0 = Q[0]; for (i32 j = 0; j <= m; j++) { auto q = (i64)j * ((i64)j + 1) / 2; Q0[j] = normalize(q); } for (i32 i = 1; i < n; i++) { auto Qi = Q[i]; auto Qi_1 = Q[i-1]; Qi[0] = 0; for (i32 j = 1; j <= m; j++) { auto qij = Qi[j-1]; for (i32 k = 1; k <= j; k++) { // R(i-1, k, j) auto r = Qi_1[m]; r = sub(r, Qi_1[k - 1]); r = sub(r, Qi_1[m - j]); qij = add(qij, r); } Qi[j] = qij; } } std::cout << Q(n-1, m); 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 | #include <cassert> #include <cstdint> #include <cstring> #include <algorithm> #include <iostream> #include <memory> #include <string> #include <vector> typedef int16_t i16; typedef int32_t i32; typedef int64_t i64; typedef uint8_t u8; class Tab { i32 _rows; i32 _columns; std::unique_ptr<i32[]> _data; public: Tab(i32 rows, i32 columns) : _rows(rows), _columns(columns), _data(new i32[rows * columns]) {} i32 * operator[](i32 row) { return row * _columns + _data.get(); } i32 & operator()(i32 row, i32 column) { return _data[row * _columns + column]; } }; i32 prime; inline i32 normalize(i64 a) { return a % prime; } inline i32 add(i32 a, i32 b) { assert(0 <= a); assert(a < prime); assert(0 <= b); assert(b < prime); auto x = a + b; return (x > prime) ? x - prime : x; } inline i32 sub(i32 a, i32 b) { assert(0 <= a); assert(a < prime); assert(0 <= b); assert(b < prime); auto x = a - b; return (x < 0) ? x + prime : x; } int main() { i32 n, m; std::cin >> n >> m >> prime; Tab Q(n, m+1); auto Q0 = Q[0]; for (i32 j = 0; j <= m; j++) { auto q = (i64)j * ((i64)j + 1) / 2; Q0[j] = normalize(q); } for (i32 i = 1; i < n; i++) { auto Qi = Q[i]; auto Qi_1 = Q[i-1]; Qi[0] = 0; for (i32 j = 1; j <= m; j++) { auto qij = Qi[j-1]; for (i32 k = 1; k <= j; k++) { // R(i-1, k, j) auto r = Qi_1[m]; r = sub(r, Qi_1[k - 1]); r = sub(r, Qi_1[m - j]); qij = add(qij, r); } Qi[j] = qij; } } std::cout << Q(n-1, m); return 0; } |