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