Submission #5942337
Source Code Expand
/* Blog: https://misteer.hatenablog.com/entry/diverta2019-2-E */
#include <iostream>
#include <vector>
template <int MOD>
class ModInt {
using lint = long long;
public:
int val;
// constructor
ModInt(lint v = 0) : val(v % MOD) {
if (val < 0) val += MOD;
};
// assignment
ModInt& operator=(const ModInt& x) {
if (this != &x) { this->val = x.val; }
return *this;
}
// unary operator
ModInt operator+() const { return ModInt(val); }
ModInt operator-() const { return ModInt(MOD - val); }
ModInt operator~() const { return *this ^ (MOD - 2); }
// increment / decrement
ModInt& operator++() { return *this += 1; }
ModInt& operator--() { return *this -= 1; }
ModInt operator++(int) {
ModInt before = *this;
++(*this);
return before;
}
ModInt operator--(int) {
ModInt before = *this;
--(*this);
return before;
}
// arithmetic
ModInt operator+(const ModInt& x) const { return ModInt(*this) += x; }
ModInt operator-(const ModInt& x) const { return ModInt(*this) -= x; }
ModInt operator*(const ModInt& x) const { return ModInt(*this) *= x; }
ModInt operator%(const ModInt& x) const { return ModInt(*this) %= x; }
ModInt operator/(const ModInt& x) const { return ModInt(*this) /= x; }
ModInt operator^(const ModInt& x) const { return ModInt(*this) ^= x; }
// compound assignment
ModInt& operator+=(const ModInt& x) {
if ((val += x.val) >= MOD) val -= MOD;
return *this;
}
ModInt& operator-=(const ModInt& x) {
if ((val -= x.val) < 0) val += MOD;
return *this;
}
ModInt& operator*=(const ModInt& x) {
val = lint(val) * x.val % MOD;
return *this;
}
ModInt& operator%=(const ModInt& x) {
val %= x.val;
return *this;
}
ModInt& operator/=(const ModInt& x) { return *this *= ~x; }
ModInt& operator^=(const ModInt& x) {
int n = x.val;
ModInt b = *this;
if (n < 0) n = -n, b = ~b;
*this = 1;
while (n > 0) {
if (n & 1) *this *= b;
n >>= 1;
b *= b;
}
return *this;
}
// compare
bool operator==(const ModInt& b) const { return val == b.val; }
bool operator!=(const ModInt& b) const { return val != b.val; }
bool operator<(const ModInt& b) const { return val < b.val; }
bool operator<=(const ModInt& b) const { return val <= b.val; }
bool operator>(const ModInt& b) const { return val > b.val; }
bool operator>=(const ModInt& b) const { return val >= b.val; }
// I/O
friend std::ostream& operator<<(std::ostream& os, const ModInt& x) noexcept { return os << x.val; }
friend std::istream& operator>>(std::istream& is, ModInt& x) noexcept { return is >> x.val; }
};
template <int MOD>
class Combination {
using mint = ModInt<MOD>;
private:
int MAX_V;
std::vector<mint> f, invf;
public:
explicit Combination(int N)
: MAX_V(N), f(MAX_V + 1), invf(MAX_V + 1) {
f[0] = 1;
for (int i = 1; i <= MAX_V; ++i) {
f[i] = f[i - 1] * i;
}
invf[MAX_V] = ~f[MAX_V];
for (int i = MAX_V - 1; i >= 0; --i) {
invf[i] = invf[i + 1] * (i + 1);
}
}
mint fact(int n) const { return f[n]; }
mint invfact(int n) const { return invf[n]; }
mint perm(int a, int b) const {
return a < b ? mint(0) : f[a] * invf[a - b];
}
mint comb(int a, int b) const {
return a < b ? mint(0) : f[a] * invf[a - b] * invf[b];
}
};
using namespace std;
constexpr int MOD = 1e9 + 7;
using mint = ModInt<MOD>;
const Combination<MOD> C(1 << 20);
int main() {
/* ----- 入力 ----- */
int N, H, D;
cin >> N >> H >> D;
/* ----- 1! + ... + N! ----- */
mint fsum = 0;
for (int l = 1; l <= N; ++l) {
fsum += C.fact(l);
}
/* ----- DP ----- */
vector<mint> dp(H + 1, 0), dpsum(H + 1, 0);
dp[0] = dpsum[0] = C.fact(N) / fsum;
// dp[h] = ブロック数の最大値がhで、そのような山の数が1個となるような操作数
for (int h = 1; h <= H; ++h) {
dp[h] = fsum * (dpsum[h - 1] -
(h - D - 1 >= 0 ? dpsum[h - D - 1] : 0));
dpsum[h] = dpsum[h - 1] + dp[h];
}
cout << dp[H] << endl;
return 0;
}
Submission Info
| Submission Time | |
|---|---|
| Task | E - Balanced Piles |
| User | Tiramister |
| Language | C++14 (GCC 5.4.1) |
| Score | 800 |
| Code Size | 4574 Byte |
| Status | AC |
| Exec Time | 34 ms |
| Memory | 16256 KiB |
Judge Result
| Set Name | Sample | All | ||||
|---|---|---|---|---|---|---|
| Score / Max Score | 0 / 0 | 800 / 800 | ||||
| Status |
|
|
| Set Name | Test Cases |
|---|---|
| Sample | s1.txt, s2.txt, s3.txt |
| All | 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, 19.txt, 20.txt, 21.txt, 22.txt, 23.txt, 24.txt, 25.txt, 26.txt, 27.txt, 28.txt, 29.txt, 30.txt, 31.txt, 32.txt, 33.txt, 34.txt, 35.txt, 36.txt, 37.txt, 38.txt, 39.txt, s1.txt, s2.txt, s3.txt |
| Case Name | Status | Exec Time | Memory |
|---|---|---|---|
| 01.txt | AC | 19 ms | 8448 KiB |
| 02.txt | AC | 19 ms | 8448 KiB |
| 03.txt | AC | 19 ms | 8448 KiB |
| 04.txt | AC | 19 ms | 8448 KiB |
| 05.txt | AC | 19 ms | 8448 KiB |
| 06.txt | AC | 19 ms | 8448 KiB |
| 07.txt | AC | 19 ms | 8448 KiB |
| 08.txt | AC | 19 ms | 8448 KiB |
| 09.txt | AC | 26 ms | 12416 KiB |
| 10.txt | AC | 28 ms | 13568 KiB |
| 11.txt | AC | 31 ms | 15744 KiB |
| 12.txt | AC | 19 ms | 8576 KiB |
| 13.txt | AC | 22 ms | 10624 KiB |
| 14.txt | AC | 20 ms | 9344 KiB |
| 15.txt | AC | 23 ms | 10752 KiB |
| 16.txt | AC | 19 ms | 8448 KiB |
| 17.txt | AC | 19 ms | 8448 KiB |
| 18.txt | AC | 20 ms | 8448 KiB |
| 19.txt | AC | 19 ms | 8448 KiB |
| 20.txt | AC | 19 ms | 8448 KiB |
| 21.txt | AC | 24 ms | 10880 KiB |
| 22.txt | AC | 28 ms | 13312 KiB |
| 23.txt | AC | 33 ms | 16128 KiB |
| 24.txt | AC | 30 ms | 14720 KiB |
| 25.txt | AC | 21 ms | 8960 KiB |
| 26.txt | AC | 33 ms | 16256 KiB |
| 27.txt | AC | 34 ms | 16256 KiB |
| 28.txt | AC | 33 ms | 16256 KiB |
| 29.txt | AC | 34 ms | 16256 KiB |
| 30.txt | AC | 34 ms | 16256 KiB |
| 31.txt | AC | 34 ms | 16256 KiB |
| 32.txt | AC | 34 ms | 16256 KiB |
| 33.txt | AC | 34 ms | 16256 KiB |
| 34.txt | AC | 34 ms | 16256 KiB |
| 35.txt | AC | 34 ms | 16256 KiB |
| 36.txt | AC | 34 ms | 16256 KiB |
| 37.txt | AC | 34 ms | 16256 KiB |
| 38.txt | AC | 19 ms | 8448 KiB |
| 39.txt | AC | 32 ms | 16256 KiB |
| s1.txt | AC | 19 ms | 8448 KiB |
| s2.txt | AC | 19 ms | 8448 KiB |
| s3.txt | AC | 19 ms | 8576 KiB |