P2424

P2424 约数和

约数和
很明显需要使用前缀和。
只想到了O(n)的做法,大概就是对于y而言枚举1~y所有数字,每一个数字i会被y/i个数字整除,于是会产生y/i*i的贡献。对这个贡献求和即可。
枚举下来就是O(n)的算法。
看题解得到了一种O(\(\sqrt n\))的算法。
就是达标发现y/i这样的数字有大量重复并且连续的,所以我们可以把这些重复的数据使用等差数列求和的方式计算出来。那么对于y/i这样的数字又有多少呢?y/(y/i)个。
最后计算答案即可。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <time.h>

#define ll long long
using namespace std;
//const ll N = 1e7;
//ll sum[N];
ll sum(ll x){
     ll l = 1,sum = 0;
     while(l <= x){
         ll r = x/(x/l);
         sum += (x/l)*(l+r)*(r-l+1)/2;
         l = r+1;
     }
     return sum;
}
int main(){
    ios::sync_with_stdio(false);
    ll x,y;cin>>x>>y;
    cout<<sum(y)-sum(x-1)<<endl;
    return 0;
}
posted @ 2021-10-13 22:24  Paranoid5  阅读(47)  评论(0编辑  收藏  举报