2020牛客暑期多校训练营(第七场):H题 Dividing (思维+整除分块)

传送门

这道题运用了整除分块的思想
这是一位大佬写的整除分块的讲解,按照他讲的推一下就懂!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;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值