牛客網Dividing
阿新 • • 發佈:2020-08-02
連結: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 \le n \le N, 1 \le k \le K1≤n≤N,1≤k≤K.
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> usingView Codenamespace 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; }