P2424 约数和

找到这个题了,顺便A掉美滋滋。

这道题用到一个非常有用的结论。没这个结论还没得做:

\[\sum_{i=1}^{n}{d_1(i)} = \sum_{i=1}^{n}{\lfloor \frac{n}{i} \rfloor \times i} \]

注意:整体还有等于,一个的话没有等于。

如果这个范围小一点的话可以用线性筛搞掉,但是范围太大了无法开下数组。所以转换为右边那种。

右边这种的话就有除法分块可以用了。不懂的话自己举个例子看看就可以了。

原理是会有一些地方的商是相同的,直接一次性算掉。

据说复杂度是\(O(\sqrt{n})\)的。

对了,要用差分的思想,求出两个之后减一下就是答案了。

只要开long long就可以了。

代码:

#include<cstdio>
#include<algorithm>
#define ll long long

ll solve(ll n)
{
    ll ans = 0;
    ll pos = 1;
    while(pos <= n)
    {
        ll val = n / pos;
        ll endpos = std::min(n / val, n);
        ans += ((pos + endpos) * (endpos - pos + 1) / 2) * val;
        pos = endpos + 1;
    }
    return ans;
}
int main()
{
    ll x, y; scanf("%lld%lld", &x, &y);
    ll temp1 = 0, temp2 = 0;
    temp1 = solve(y);
    temp2 = solve(x - 1);
    printf("%lld\n", temp1 - temp2);
    return 0;
}
posted @ 2018-10-06 16:13  Garen-Wang  阅读(172)  评论(0编辑  收藏  举报