#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; } |
English