#define _CRT_SECURE_NO_WARNINGS
#define ONLINE_JUDGE
#include <iostream>
#include <cassert>
#include <vector>
using namespace std;
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
typedef long long LL;
class Solver
{
public:
int solve(LL rails, LL segments, LL prime)
{
if (segments == 1)
return 1;
this->rails = rails;
this->segments = segments;
this->prime = prime;
paintings = vector<vector<LL>>(rails + 1, vector<LL>(segments + 1, 0));
fillForFirstRail();
FOR(rail, 2, rails)
{
paintings[rail][1] = paintings[rail - 1][segments] + (prime - paintings[rail - 1][segments - 1]);
paintings[rail][1] %= prime;
vector<LL> sumOfPaintingsOfPreviousRailUpToIndex(segments + 1, 0);
FOR(k, 1, segments)
{
sumOfPaintingsOfPreviousRailUpToIndex[k] = sumOfPaintingsOfPreviousRailUpToIndex[k - 1];
sumOfPaintingsOfPreviousRailUpToIndex[k] += (prime - paintings[rail - 1][k - 1]);
sumOfPaintingsOfPreviousRailUpToIndex[k] %= prime;
}
FOR(segment, 2, segments)
{
paintings[rail][segment] = paintings[rail][segment - 1];
paintings[rail][segment] += paintings[rail - 1][segments] * segment;
paintings[rail][segment] %= prime;
paintings[rail][segment] += (prime - paintings[rail - 1][segments - segment]) * segment;
paintings[rail][segment] %= prime;
paintings[rail][segment] += sumOfPaintingsOfPreviousRailUpToIndex[segment];
paintings[rail][segment] %= prime;
}
}
return paintings[rails][segments];
}
private:
void fillForFirstRail()
{
for (int segment = 1; segment <= segments; ++segment)
paintings[1][segment] = (paintings[1][segment - 1] + segment % prime);
}
vector<vector<LL>> paintings;
LL rails;
LL segments;
LL prime;
};
int main()
{
Solver solver;
#ifndef ONLINE_JUDGE
const int randomPrime = 100000007;
assert(solver.solve(1, 1, randomPrime) == 1);
for (int rails = 2; rails <= 100; ++rails)
assert(solver.solve(rails, 1, randomPrime) == 1);
assert(solver.solve(1, 2, randomPrime) == 3);
assert(solver.solve(1, 3, randomPrime) == 6);
assert(solver.solve(1, 4, randomPrime) == 10);
assert(solver.solve(1, 5, randomPrime) == 15);
assert(solver.solve(3, 2, randomPrime) == 17);
assert(solver.solve(6, 9, 813443923) == 57);
printf("Tests finished.\n");
#endif
int rails, segments, prime;
scanf("%d %d %d", &rails, &segments, &prime);
printf("%d\n", solver.solve(rails, segments, prime));
#ifndef ONLINE_JUDGE
system("pause");
#endif
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 92 | #define _CRT_SECURE_NO_WARNINGS #define ONLINE_JUDGE #include <iostream> #include <cassert> #include <vector> using namespace std; #define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i) typedef long long LL; class Solver { public: int solve(LL rails, LL segments, LL prime) { if (segments == 1) return 1; this->rails = rails; this->segments = segments; this->prime = prime; paintings = vector<vector<LL>>(rails + 1, vector<LL>(segments + 1, 0)); fillForFirstRail(); FOR(rail, 2, rails) { paintings[rail][1] = paintings[rail - 1][segments] + (prime - paintings[rail - 1][segments - 1]); paintings[rail][1] %= prime; vector<LL> sumOfPaintingsOfPreviousRailUpToIndex(segments + 1, 0); FOR(k, 1, segments) { sumOfPaintingsOfPreviousRailUpToIndex[k] = sumOfPaintingsOfPreviousRailUpToIndex[k - 1]; sumOfPaintingsOfPreviousRailUpToIndex[k] += (prime - paintings[rail - 1][k - 1]); sumOfPaintingsOfPreviousRailUpToIndex[k] %= prime; } FOR(segment, 2, segments) { paintings[rail][segment] = paintings[rail][segment - 1]; paintings[rail][segment] += paintings[rail - 1][segments] * segment; paintings[rail][segment] %= prime; paintings[rail][segment] += (prime - paintings[rail - 1][segments - segment]) * segment; paintings[rail][segment] %= prime; paintings[rail][segment] += sumOfPaintingsOfPreviousRailUpToIndex[segment]; paintings[rail][segment] %= prime; } } return paintings[rails][segments]; } private: void fillForFirstRail() { for (int segment = 1; segment <= segments; ++segment) paintings[1][segment] = (paintings[1][segment - 1] + segment % prime); } vector<vector<LL>> paintings; LL rails; LL segments; LL prime; }; int main() { Solver solver; #ifndef ONLINE_JUDGE const int randomPrime = 100000007; assert(solver.solve(1, 1, randomPrime) == 1); for (int rails = 2; rails <= 100; ++rails) assert(solver.solve(rails, 1, randomPrime) == 1); assert(solver.solve(1, 2, randomPrime) == 3); assert(solver.solve(1, 3, randomPrime) == 6); assert(solver.solve(1, 4, randomPrime) == 10); assert(solver.solve(1, 5, randomPrime) == 15); assert(solver.solve(3, 2, randomPrime) == 17); assert(solver.solve(6, 9, 813443923) == 57); printf("Tests finished.\n"); #endif int rails, segments, prime; scanf("%d %d %d", &rails, &segments, &prime); printf("%d\n", solver.solve(rails, segments, prime)); #ifndef ONLINE_JUDGE system("pause"); #endif return 0; } |
English