题解| 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;
}
posted @ 2021-08-25 14:40  RioTian  阅读(66)  评论(0编辑  收藏  举报