2020牛客暑期多校训练营(第七场)H
Dividing
https://ac.nowcoder.com/acm/contest/5672/H
题目描述
The following rules define a kind of integer tuple - the Legend Tuple:
is always a Legend Tuple, where k is an integer.
if is a Legend Tuple, is also a Legend Tuple.
if is a Legend Tuple, is also a Legend Tuple.
We want to know the number of the Legend Tuples where , .
In order to avoid calculations of huge integers, report the answer modulo instead.
输入描述
The input contains two integers and , .
输出描述
Output the answer modulo .
示例1
输入
3 3
输出
8
示例2
输入
3 9
输出
14
分析
所有 Legend Tuple 从 出发,会产生 和 两种情况();其中, 的情况经过一步操作可以变成 的情况。
显然,当且仅当 或 时, 为 Legend Tuple。
对于 的情况,其贡献为 ; 为 的贡献, 为 的贡献。
对于 的情况,其贡献为 。
对于两部分贡献,有 这部分的贡献是重复的,需要减去重复的一份贡献 。
因此最终的答案为 。可以用数论分块解决。
当然, 或 时需要进行特判:当 ,答案为 ;当 ,答案为 。
代码
/****************************************************************** Copyright: 11D_Beyonder All Rights Reserved Author: 11D_Beyonder Problem ID: 2020牛客暑期多校训练营(第七场)Problem H Date: 8/28/2020 Description: Block *******************************************************************/ #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const ll mod=1000000007; ll N,K; ll cal(ll n,ll k){ //数论分块 ll l,r; ll ans=0; for(l=1;l<=k;l=r+1){ if(n/l==0){ break; } r=min(k,n/(n/l)); ans+=(r-l+1)*(n/l)%mod; ans%=mod; } return ans; } int main(){ cin>>N>>K; if(N==1){ cout<<K%mod<<endl; }else if(K==1){ cout<<N%mod<<endl; }else{ cout<<((cal(N,K)+cal(N-1,K)+K-N)%mod+mod)%mod<<endl; } return 0; }
牛客暑期多校训练营题解 文章被收录于专栏
收集牛客暑期多校训练营的题解