AT ARC192D Fraction Line
结果 D 居然是 BCD 中最简单的一道吗。
首先从第一个条件入手,因为这个条件看着比第二个条件限制更严。
考虑打开 \(f\) 这个式子:\(f\left(\dfrac{S_i}{S_{i + 1}}\right) = \dfrac{S_i S_{i + 1}}{\gcd^2(S_i, S_{i + 1})} = A_i\)。
接下来考虑刻画 \(\dfrac{S_i S_{i + 1}}{\gcd^2(S_i, S_{i + 1})}\),就可以与 \(A_i\) 对比得到信息。
注意到乘积和 \(\gcd\) 都是可以拆分为质数组合而成的,所以考虑分解 \(S_i = \prod\limits_{k} p_k^{e_{i, k}}(p_k\in \mathbb{P})\)。
那么对于 \(p_k\) 来说,其对这个式子的贡献就是 \(\dfrac{p_k^{e_{i, k} + e_{i + 1, k}}}{p_k^{2\min\{e_{i, k}, e_{i + 1, k}\}}} = p_k^{|e_{i, k} - e_{i + 1, k}|}\)。
那么此时左式被拆成了 \(p_k\) 单独考虑,对于右式 \(A_i\) 也这样做,那么分解 \(A_i = \prod\limits_{k} p_k^{c_{i, k}}\)。
那么根据左式 \(=\) 右式,就应该有对于任意 \(p_k\),都有 \(\forall i\in [1, n), |e_{i, k} - e_{i + 1, k}| = c_{i, k}\)。
接下来考虑第二个条件:\(\gcd\left(S_1, S_2, \cdots, S_n\right) = 1\)。
因为前面已经对于了每个 \(p_k\) 拆开考虑,所以这个条件依然对于每个 \(p_k\) 考虑。
这个条件相当于是限制了对于 \(p_k\) 贡献给 \(\gcd\) 一定是 \(p_k^0 = 1\)。
所以这个条件可以转化为对于任意 \(p_k\),\(\min\{e_{1, k}, e_{2, k}, \cdots, e_{n, k}\} = 0\)。
因为上面的条件都是针对拆开 \(S_i\) 分析的,所以还要考虑组合有没有什么问题。
因为这题是拆分成了 \(S_i = \prod\limits_{k} p_k^{e_{i, k}}\),所以不同的 \((e_{i, 1}, e_{i, 2}, \cdots)\) 都会对应上不同的 \(S_i\)。
于是根据分析,可以直接考虑对于每个 \(p_k\) 来计数,最后再组合成 \(S\)。
首先考虑要组合出最终答案,每个 \(p_k\) 需要知道什么信息。
首先考虑只有 \(p_1, p_2\),答案该如何表示。
写出式子:\(\sum\limits_{e_{1\sim n, 1}}\sum\limits_{e_{1\sim n, 2}} \prod\limits_{i = 1}^n p_1^{e_{i, 1}}p_2^{e_{i, 2}} = \sum\limits_{e_{1\sim n, 1}}\sum\limits_{e_{1\sim n, 2}} \left(\prod\limits_{i = 1}^n p_1^{e_{i, 1}}\right)\times \left(\prod\limits_{i = 1}^n p_2^{e_{i, 2}}\right) = \left(\sum\limits_{e_{1\sim n, 1}} \prod\limits_{i = 1}^n p_1^{e_{i, 1}}\right)\times \left(\sum\limits_{e_{1\sim n, 2}} \prod\limits_{i = 1}^n p_2^{e_{i, 2}}\right)\)。
那么这个是可以继续推广下去到 \(p_{1, 2, \cdots}\) 的。
于是可以发现对于每个 \(p_k\) 只需要知道 \(\sum\limits_{e_{1\sim n, k}} \prod\limits_{i = 1}^n p_k^{e_{i, k}}\) 的值。
那接下来就考虑如何对于每个 \(p_k\) 来统计其答案。
首先 \(c_{i, k}\) 是可以预处理出来的。
因为 \(\min\{e_{1, k}, e_{2, k}, \cdots, e_{n, k}\} = 0\),所以 \(\max\{e_{1, k}, e_{2, k}, \cdots, e_{n, k}\} \le \sum\limits_{i = 1}^{n - 1} c_{i, k}\)。
发现这个 \(e_{i, k}\) 的值域不是很大,同时 DP 的时候关心 \(p_k^{e_{i, k}}\) 这个值,于是可以针对 \(e_{i, k}\) 的值设计 DP:
设 \(f_{i, j, 0 / 1}\) 表示 \(e_{i, k} = j\),是否存在 \(1\le i'\le i\) 使得 \(e_{i', k} = 0\) 的 \(\sum\limits_{e_{1\sim i, k}}\prod\limits_{i' = 1}^{i} p_k^{e_{i', k}}\)。
关于转移,只需要考虑 \(e_{i + 1, k} = j + c_{i, k}\) 和 \(e_{i + 1, k} = j - c_{i, k}\) 两种情况即可,注意 \(c_{i, k} = 0\) 会算重。
对于单个 \(p_k\),DP 的复杂度是 \(\mathcal{O}\left(n\sum\limits_{i = 1}^{n - 1}c_{i, k}\right)\)。
那么总的 DP 的复杂度是 \(\mathcal{O}\left(\sum\limits_{k} \left(n\sum\limits_{i = 1}^{n - 1}c_{i, k}\right)\right) = \mathcal{O}\left(n \sum\limits_{k}\sum\limits_{i = 1}^{n - 1} c_{i, k}\right)\le \mathcal{O}(n^2\log V)\)。
带上预处理 \(c_{i, k}\) 的复杂度(\(n, V\) 不大随便做)的总复杂度是 \(\mathcal{O}(nV + n^2\log V)\)。
#include<bits/stdc++.h>
using ll = long long;
constexpr ll mod = 998244353;
constexpr int maxn = 1e3 + 10, V = 1e3;
std::bitset<V + 1> pr;
int n, cnt[V + 1][maxn];
ll f[maxn][maxn * 11][2];
ll pw[maxn * 11];
int main() {
for (int p = 2; p <= V; p++) {
if (pr[p]) continue;
for (int i = p + p; i <= V; i += p) {
pr[i] = 1;
}
}
scanf("%d", &n);
for (int i = 1, x; i < n; i++) {
scanf("%d", &x);
for (int p = 2; p <= V; p++) {
while (x % p == 0) {
cnt[p][i]++, x /= p;
}
}
}
ll ans = 1ll;
for (int p = 2; p <= V; p++) {
if (pr[p]) continue;
int *cp = cnt[p], m = 0;
for (int i = 1; i < n; i++) m += cp[i];
for (int c = pw[0] = 1; c <= m; c++) pw[c] = pw[c - 1] * p % mod;
for (int i = 1; i <= n; i++) {
for (int c = 0; c <= m; c++) {
for (int o : {0, 1}) {
f[i][c][o] = 0;
}
}
}
for (int c = 0; c <= m; c++) f[1][c][0]++;
ll tot = 0;
for (int i = 1; i <= n; i++) {
(f[i][0][1] += f[i][0][0]) %= mod, f[i][0][0] = 0;
for (int c = 0; c <= m; c++) {
for (int o : {0, 1}) {
(f[i][c][o] *= pw[c]) %= mod;
if (i == n) {
(tot += f[i][c][o] * o) %= mod;
continue;
}
if (cp[i] == 0) {
(f[i + 1][c][o] += f[i][c][o]) %= mod;
continue;
}
if (c + cp[i] <= m) {
(f[i + 1][c + cp[i]][o] += f[i][c][o]) %= mod;
}
if (c - cp[i] >= 0) {
(f[i + 1][c - cp[i]][o] += f[i][c][o]) %= mod;
}
}
}
}
(ans *= tot) %= mod;
}
printf("%lld\n", ans);
return 0;
}
浙公网安备 33010602011771号