给出正整数n和k,计算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值。
例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7。
输入格式
输入仅一行,包含两个整数n, k。
输出格式
输出仅一行,即j(n, k)。
数据范围
1≤n,k≤109
输入样例:
5 3
输出样例:
7
做法:除法分块: k%i=k-(k/i)*i
推导过程: f(n,k)=k%1+k%2+k%3+...+k%n
(用上述公式k%i=k-(k/i)*i) =k-k/1*1+k-k/2*2+...k-k/n*n
=n*k-sum((k/i)*i)(其中i从1到n)
因为(k/i)*i的括号内后面都是等差数列,在当前a1=i时,找最大的与k/a1相等的an,即:k/an=k/a1,所以an=k/(k/a1),为了处理边界,所以与n取min,最后每次用等差数列算出一系列(k/a1)的和,然后乘k/a1,ans初始为n*k,每次让ans减去这个求和的结果即可。
完整代码:
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
int n,k,a1,an;
signed main()
{
cin>>n>>k;
int ans=n*k;
for(int a1=1;a1<=n;a1=an+1){
an=k/a1?min(k/(k/a1),n):n;
ans-=k/a1*(a1+an)*(an-a1+1)/2;
}
cout<<ans<<endl;
return 0;
}