牛客题目
链接:https://ac.nowcoder.com/acm/contest/5672/H
The following rules define a kind of integer tuple - the Legend Tuple:
(1, k) is always a Legend Tuple, where k is an integer.
if (n, k) is a Legend Tuple, (n + k, k) is also a Legend Tuple.
if (n, k) is a Legend Tuple, (nk, k) is also a Legend Tuple.
We want to know the number of the Legend Tuples (n, k) where 1≤n≤N,1≤k≤K.
In order to avoid calculations of huge integers, report the answer modulo 10^9+7 instead.
输入描述:
The input contains two integers N and K, 1≤N,K≤10 ^12
.
输出描述:
Output the answer modulo 10^9+7
只有在满足n=1,n是k的倍数,或者n-1是k的倍数时,(n,k)是传奇元组。
因此,我们可以认为(n,k)是传奇元组,当且仅当n可以-k或/k,最后变成1。得到以下两种操作:
如果n是k的倍数,即n=xk,那么可以减掉(x-1)个k,将n变为k,再/k为1。
而如果n-1是k的倍数,即n=xk+1,那么x次除k就行
题解来自 https://ac.nowcoder.com/acm/discuss/blogs?tagId=137443 TitanZhang
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 106;
const ll mod = 1e9+7;
const double inf = 0x3f3f3f3f;
const double eps = 1e-6;
const double e = exp(1);
const double pi = acos(-1.0);
ll n, k, ans;
void solve(ll n)
{
ll 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; //略过取模运算,就是 ans += (j-i+1)*(n/i), 由上一步可知 n/a = n/i, a∈ [i, j] , 可以减少几步计算 n/i, n/(i+1), n/(i+1),,,,有点机智 QΩQ
}
}
int main()
{
scanf("%lld%lld", &n, &k);
solve(n);
solve(n-1);
printf("%lld\n", (ans+n+k-1)%mod);
return 0;
}