2020牛客暑期多校训练营(第七场)H-Dividing (数学/分块整除)

Dividing

题目大意:定义(1,k)为传奇元组

  • 如果(n,k)是传奇元组的话,(n*k,k)也是传奇元组
  • 如果(n,k)是传奇元组的话,(n+k,k)也是传奇元组

解题思路:

题意第二条可以转换一下,因为n只能加k或者乘k,而n起始为1,所以n一定为k的倍数或者n%k==1,即(n+k,k)可以转换成 (n*k+1,k)–>n-1是k的倍数。

所以问题就变成了 n=x * k 或者 n-1=x * k;
这里要注意一下 n 和 k 的范围是不一样的,如果k小于等于n,那么运算到k即可,而k大于n时,运算到n截断即可–> j=min(n/(n/i),k)
剩下就是整除分块的问题了,跑一下模板就odk了。

(ans+n+k-1)%mod)–> +n+k-1 最终答案加上下图黑色的传奇元组
在这里插入图片描述

Code:

#include<bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
long long n,k,ans;
void find(long long n)
{
    long long i,j;
    for(i=2;i<=n && i<=k;i=j+1)
    {
        j=min(n/(n/i),k);
        (ans+=(j-i+1)%mod*(n/i)%mod)%=mod;
    }
}
int main()
{
    scanf("%lld%lld",&n,&k);
    find(n);find(n-1);
    printf("%lld\n",(ans+n+k-1)%mod);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_43872264/article/details/107738242