思路:
题意可以等价为求
满足
,且
这个可以对于x=1或者y=1的情况单独考虑,结果为n+k-1。
对于x≥2和y≥2,模数为0的时候,此时其实就是寻找对于[2,k]中每个数为其倍数,在前n个数中存在多少个数为其倍数。
这个过程可以用除法分块解决。对于x,寻找前n个数中有多少个数为其倍数,其实就是 。而除法分块是寻找对于 ,存在多少个 满足这个式子的值相同。
模数为1的时候也是一样,就是将n变成n-1。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <iostream>
#include <map>
#include <string>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int maxn = 5000 + 7;
ll get1(ll n,ll k) {
ll ans = n;
ll r = 2,l = 2;
for(;l <= k;l = r + 1) {
if(n / l == 0) r = k;
else r = min(k,n / (n / l));
ans += n / l % mod * ((r - l + 1) % mod);
ans %= mod;
}
return ans;
}
ll get2(ll n,ll k) {
ll ans = k - 1;
ll r = 2,l = 2;
for(;l <= k;l = r + 1) {
if(n / l == 0) r = k;
else r = min(k,n / (n / l));
ans += n / l % mod * ((r - l + 1) % mod);
ans %= mod;
}
return ans;
}
int main() {
ll n,k;scanf("%lld%lld",&n,&k);
ll ans = get1(n,k) + get2(n - 1,k);
printf("%lld\n",ans % mod);
return 0;
}