Dividing
链接: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≤K1.
In order to avoid calculations of huge integers, report the answer modulo 109+710^9+7109+7 instead.
输入描述:
The input contains two integers N and K, 1≤N,K≤1e12.
输出描述:
Output the answer modulo 1e9+7
充分性简要证明 :
我们可以认为 (n, k) 是一个 Legned Tuple 当且仅当可以通过将 n 通过减 k 和 除以 k 两种操作变为 1
若 n 是 k 的倍数, 设 n=xk, 我们可以先执行 (x-1) 次 减 k 操作, 使得 n 变成 xk-(x-1)k=k, 最后执行 一次除以 k 操作即可
若 n – 1 是 k 的倍数, 设 n=xk+1, 那么执行 x 次除以 k 操作即可
然后在时间复杂度O(n)的基础上压一压即可。
代码:
#include<bits/stdc++.h> using namespace std; long long n,k,f; long long num,t; long long ans,sum; long long mod=1e9+7; int main() { cin>>n>>k; ans=k; ans+=n-1; ans%=mod; for(long long i=2; i<=min(n,k); i=sum+1) { sum=n/(n/i); sum=min(sum,k); sum=min(sum,n); ans+=(n/i)%mod*((sum-i+1)%mod)%mod; ans%=mod; } n--; for(long long i=2; i<=min(n,k); i=sum+1) { sum=n/(n/i); sum=min(sum,k); sum=min(sum,n); ans+=(((n/i)%mod)*((sum-i+1)%mod))%mod; ans%=mod; } cout<<ans%mod<<endl; }