原题
题目描述
定义传奇元组
:
:
:
●
(
1
,
k
)
(1,k)
(1,k)始终是传奇元组,其中k是整数。
● 如果
(
n
,
k
)
(n,k)
(n,k)是传奇元组,
(
n
+
k
,
k
)
(n+k,k)
(n+k,k)与
(
n
k
,
k
)
(nk,k)
(nk,k)也是传奇元组。
我们想知道
1
≤
n
≤
N
1≤n≤N
1≤n≤N,
1
≤
k
≤
K
1≤k≤K
1≤k≤K时传奇元组
(
n
,
k
)
(n,k)
(n,k)的数目。
输入描述
输入包含两个整数
N
N
N和
K
K
K,
1
≤
N
1≤N
1≤N,
K
≤
K≤
K≤
10
10
1012。
输出描述
输出答案,取模
10
10
109
+
7
+7
+7。
样例1
输入
3 3
输出
8
样例2
输入
3 9
输出
14
思路
一拍脑袋,我们会知道由
(
n
,
k
)
(n,k)
(n,k)推出的
(
n
k
,
k
)
(nk,k)
(nk,k)的传奇元组,
n
n
n必定是
k
k
k的倍数;而如果没有, 那么肯定是
(
x
k
+
1
,
k
)
(xk+1,k)
(xk+1,k)的形式。
所以只有在满足
n
=
1
n=1
n=1,
n
n
n是
k
k
k的倍数,或者
n
−
1
n-1
n−1是
k
k
k的倍数时,
(
n
,
k
)
(n,k)
(n,k)是传奇元组。
- 若 n = x k n=xk n=xk,则 x x x和 k k k中肯定有一个数字不超过 10 10 106,所以只要枚举 k k k和 n n n中较小的数字即可,另外一个的个数可以通过计算得出。
- 若 n = x k + 1 n=xk+1 n=xk+1,则和上面的情况相同。
- 若
n
=
1
n=1
n=1,直接统计即可。
具体细节可以看以下代码。
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;
ll n,m,sum;
void solve(ll a,ll b)
{
b=min(a,b);
for (ll l=2,r;l<=b;l=r+1)r=min(b,(a/(a/l))),sum=(sum+(r-l+1)%mod*(a/l));
}
int main()
{
scanf("%lld%lld",&n,&m);
solve(n,m);solve(n-1,m);
printf("%lld",((sum+n)%mod+m-1)%mod);
return 0;
}