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;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9747596.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值