E - Dice Product 3 Editorial by en_translator
Consider solving this problem with a DP (Dynamic Programming). Let
\(\mathrm{dp}(n)\): (the probability that your integer results being \(N\), starting from the state where the your integer is \(n\));
then the answer is \(\mathrm{dp}(1)\).
We find the equation on \(\mathrm{dp}(n)\). When you cast a die, your integer changes to one of \(n, 2n, 3n, 4n, 5n, 6n\) with equal probabilities. Thus
\[\mathrm{dp}(n) = \frac{1}{6} (\mathrm{dp}(n) + \mathrm{dp}(2n) + \mathrm{dp}(3n) + \mathrm{dp}(4n) + \mathrm{dp}(5n) + \mathrm{dp}(6n) ).\]
This equation contains \(\mathrm{dp}(n)\), so we eliminate them:
\[\mathrm{dp}(n) - \frac{1}{6} \mathrm{dp}(n) = \frac{1}{6} (\mathrm{dp}(2n) + \mathrm{dp}(3n) + \mathrm{dp}(4n) + \mathrm{dp}(5n) + \mathrm{dp}(6n) )\]
\[\frac{5}{6} \mathrm{dp}(n) = \frac{1}{6} (\mathrm{dp}(2n) + \mathrm{dp}(3n) + \mathrm{dp}(4n) + \mathrm{dp}(5n) + \mathrm{dp}(6n) )\]
\[\mathrm{dp}(n) = \frac{1}{5} (\mathrm{dp}(2n) + \mathrm{dp}(3n) + \mathrm{dp}(4n) + \mathrm{dp}(5n) + \mathrm{dp}(6n) )\]
Now we have an equation regarding \(\mathrm{dp}(n)\).
Also, \(\mathrm{dp}(N) = 1\), and \(\mathrm{dp}(n) = 0\) for \(n \geq N\). Using these properties, we can see that computing \(\mathrm{dp}(n)\) with a memorized recursion terminates in a finite time.
- The left hand side is an equation about \(\mathrm{dp}(n)\), while the right hand side is about \(\mathrm{dp}(kn)\) \((2 \leq k \leq 6)\), so the deeper the recursion is, the larger the argument is. Thus, the recursion never triggers a loop.
We estimate the complexity. Let \(X\) be the number of distinct integers that can be an argument \(n\) of \(\mathrm{dp}(n)\); then, the memorized recursion using std::map
is estimated to be work in a total of \(\mathrm{O}(X \log X)\), so we evaluate the upper bound of \(X\).
The die shows only multiples of \(2, 3, 5\), so \(n\) can always be represented as \(n = 2^a 3^b 5^c\) with non-negative integers \((a, b, c)\). With \(n \leq N\), we have
\[ \begin{aligned} &0 \leq a \leq \log_2 N \leq \log_2(10^{18}) < 60 \\ &0 \leq b \leq \log_3 N \leq \log_3(10^{18}) < 38 \\ &0 \leq c \leq \log_5 N \leq \log_5(10^{18}) < 26, \end{aligned} \]
so there are at most \(60 \times 38 \times 26 = 59280\) distinct integers that can be \(n\). Hence, \(X \leq 59280\) is proven, and the DP with the memorized recursion works fast enough.
- Sample code (C++)
#include <iostream>
#include <map>
using namespace std;
#include "atcoder/modint.hpp"
using mint = atcoder::modint998244353;
long long N;
map<long long, mint> memo;
mint dp(long long n) {
if (n >= N) return n == N ? 1 : 0;
if (memo.count(n)) return memo[n];
mint res = 0;
for (int i = 2; i <= 6; i++) res += dp(i * n);
return memo[n] = res / 5;
}
int main() {
cin >> N;
cout << dp(1).val() << "\n";
}
posted:
last update: