题目链接:Here
这个思路学习自 Harris-H ,考虑递推而不是DP
与 D1 不同,开始考虑 (f_{i-1} o 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;
}