题解| CF1561D2. Up the Strip(递推)
题目链接:Here
这个思路学习自 Harris-H ,考虑递推而不是DP
与 D1 不同,开始考虑 \(f_{i-1} \to f_i\)
显然操作 1 多了 \(f_{i-1}\) ,操作2 多了 \(f_1\)
所以 \(f_i =2f_{i-1} + 1\)
除此外,所有 \(i\) 的因数都会相对于 \((i-1)\) 加 \(1\) ,因为
\(i = 4,\frac42 =2,\frac{4-1}2=1\)
类似素数筛,需要更新
- \(\mathcal{O}(n\ log\ n)\)
注意 \(f_2\) 特判
const int N = 4e6 + 10;
ll f[N];
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
ll n, m; cin >> n >> m;
f[1] = 1;
for (int i = 2; i <= n; ++i) {
if (i == 2) f[i] = 2;
else f[i] = (f[i] + 2 * f[i - 1] + 1) % m;
ll cnt = (f[i] - f[i - 1]) % m;
for (int j = i + i; j <= n; j += i)f[j] += cnt;
}
cout << (f[n] + m) % m;
}