「题解」洛谷 P2424 约数和

题目

P2424 约数和

简化题意

\(f(x) = \sum\limits_{d\mid x} d\),求\(f(x) + f(x + 1) + \dots + f(y)\) 的值

思路。

整除分块。

一个数 \(i\)\(1 \sim n\) 中它的倍数一共有 \(\left\lfloor \dfrac{n}{i} \right\rfloor\) 个,即 \(i\) 对答案的贡献为 \(\left\lfloor \dfrac{n}{i} \right\rfloor \times i\)

\(g(n)\) 表示 \(\sum\limits_{i = 1}^{n} f(i)\),原式可以用下面的方式表示,

\[\begin{aligned} g(y) - g(x - 1) &= \sum_{i = 1}^{y}f(i) - \sum_{j = 1}^{x - 1}f(j)\\ &= \sum_{i = 1} ^ {y} \sum\limits_{c\mid i} c - \sum_{j = 1}^{j - 1} \sum\limits_{d\mid j} d \end{aligned} \]

考虑先枚举约数。

\[\begin{aligned} &\sum_{i = 1} ^ {y} \sum\limits_{c\mid i} c - \sum_{j = 1}^{x - 1} \sum\limits_{d\mid j} d \\ &= \sum_{i = 1}^{y} \left\lfloor \dfrac{y}{i} \right\rfloor \times i - \sum_{j = 1}^{x - 1} \left\lfloor \dfrac{x - 1}{j} \right\rfloor \times j \end{aligned} \]

可以用整除分块 \(O(2\sqrt n)\) 求出答案。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>

long long solve(int x) {
    long long ans = 0;
    for (int i = 1, j = 0; i <= x; i = j + 1) {
        j = x / (x / i);
        ans += 1ll * (x / i) * (1ll * (j - i + 1) * (1ll * j + i) / 2);
    }
    return ans;
}

int main() {
    int x, y;
    std::cin >> x >> y;
    std::cout << solve(y) - solve(x - 1);
    return 0;
}
posted @ 2020-09-06 06:39  yu__xuan  阅读(113)  评论(0编辑  收藏  举报