1. 程式人生 > 實用技巧 >牛客網Dividing

牛客網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 \le n \le N, 1 \le k \le K1nN,1kK.

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, 1N,K1e12.

輸出描述:

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; }
View Code