H.Dividing(整除分块)

H.Dividing(整除分块)

思路:整除分块.

显然题意可以转化为:求满足 n m o d k = 0 n\bmod k=0 1 1 的对数。

n m o d k = 1 ( n 1 ) m o d k = 0 n\bmod k=1\Leftrightarrow (n-1)\bmod k=0

对于特殊情况:

k = 1 k=1 时有 n n 个, n = 1 , k > 1 n=1,k>1 时有 k 1 k-1 个。

然后我们只需计算出: i = 2 k n i + i = 2 k n 1 i \sum\limits_{i=2}^k \lfloor\dfrac{n}{i}\rfloor+\sum\limits_{i=2}^k\lfloor\dfrac{n-1}{i}\rfloor

因此可以用整除分块解决。

即:答案为: n + k 1 + i = 2 k n i + i = 2 k n 1 i n+k-1+\sum\limits_{i=2}^k \lfloor\dfrac{n}{i}\rfloor+\sum\limits_{i=2}^k\lfloor\dfrac{n-1}{i}\rfloor

时间复杂度: O ( k ) O(\sqrt{k})

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const double eps=1e-8;
const int mod=1e9+7;
ll n,k,ans=0;
void calc(ll n,ll k){
    for(ll l=2,r;l<=min(n,k);l=r+1){
        r=min(n/(n/l),k);
        ans=(ans+((r-l+1)%mod)*((n/l)%mod)%mod)%mod;
    }
}
int main(){
    scanf("%lld%lld",&n,&k);
    ans=(n+k-1)%mod;
    calc(n,k);
    calc(n-1,k);
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/107741461
今日推荐