这道题运用了整除分块的思想
这是一位大佬写的整除分块的讲解,按照他讲的推一下就懂!https://blog.csdn.net/weixin_43627118/article/details/104024380
题目大意:
- (1,k)是传奇元组
- 如果 (n,k)是传奇元组 那么 (nk,k)和(n+k,k)也是传奇元组
- 给定N,K 求有多少个(n,k)是传奇元组,其中 1 <= n <= N , 1<= k <= N,答案取模1e9 + 7
题解:
通过题目所给的条件我们可以看出,当n = 1时一定是传奇元组,(1,k)变为(n,k)时分为以下两种情况
- (nk,k) -> n是k的倍数
- (xk + 1,k)-> n-1是k的倍数
所以就得到以下结论:n = xk 或 n-1 = xk
但是要注意,当n <= k时算到底就ok,但当n > k 时就需要算到k就截断,即右端点为min(n / (n / i ), k)
接下来就是套整除分块的模板
附上一个例子
完整代码
#include <iostream>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
ll ans,k;
void f(ll n)
{
for(ll i = 2,j; i <= n && i <= k; i = j + 1)
{
j = min(n / (n / i) , k);
ans = (ans + ( j - i + 1) % mod * (n / i) % mod) % mod;
}
}
int main()
{
ll n;
cin >> n >> k;
f(n);
f(n - 1);
ans = (ans + (n + k - 1)) % mod;
cout << ans << endl;
return 0;
}