1. 程式人生 > 實用技巧 >2020牛客暑期多校訓練營(第七場) H Dividing

2020牛客暑期多校訓練營(第七場) H Dividing

Dividing

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define inf64 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 1e5+10;
/*
題解:
通過對(1,k) 的兩種變形,可以得到只要式子如同 (1+x*k,k) (x*k,k)
就可以滿足條件,然後容易發現就是列舉k n/k  和  (n-1)/k
但是這個k無法列舉,看這個式子容易想到數論分塊,所以可以用數論分塊來求。
*/

ll solve(ll n,ll k){
    ll l,r,ans = 0;
    ll len = min(n,k);
    for(l = 1,r = 0;l<=len;l=r+1){
        r = n/(n/l);
        if(r>len) break;
        ll x = (r-l+1)%mod;
        ll y = (n/l)%mod;
        ans = (ans + x*y%mod)%mod;
    }
    r = min(r*1ll,len);
    ll x = (r-l+1)%mod;
    ll y = (n/l)%mod;
    ans = (ans+ max(0ll,x)*y%mod)%mod;
    return ans;
}

int main(){
    ll n,k,ans = 0;
    scanf("%lld%lld",&n,&k);
    ans = (solve(n,k)+solve(n-1,k))%mod;
    ans = (ans - n%mod + mod)%mod;
    ans = (ans + k)%mod;
    printf("%lld\n", ans);
    return 0;
}