bookshelfTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 598 Accepted Submission(s): 273 Problem Description Patrick Star bought a bookshelf, he named it ZYG !!
Input The first line contain a integer T (no morn than 10), the following is T test case, for each test case :
Output For each test case, output the answer as a value of a rational number modulo 109+7 .
Sample Input 1 6 8
Sample Output 797202805
Source 2018 Multi-University Training Contest 6
|
贴个板子,过段时间再来写题解。。光是A过就要吐了。。
有一篇不错的分析的文:https://blog.csdn.net/codeswarrior/article/details/81565716
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2000005;
const int mod=(int)1e9+7;
int prime[maxn],numprime,mobi[maxn],vis[maxn];
ll fac[maxn],inv_fac[maxn],n,k,fib[maxn];
ll quick(ll a,ll b){
ll ans=1;
while(b){
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b/=2;
}
return ans;
}
ll C(ll n,ll m){
if(n<0||m<0||m>n) return 0;
if(n==m||m==0) return 1;
return fac[n]*inv_fac[n-m]%mod*inv_fac[m]%mod;
}
void initmob(){//莫比乌斯反演
mobi[1]=1;
for(int i=2;i<maxn;i++){
if(!vis[i]){
prime[++numprime]=i;
mobi[i]=-1;
}
for(ll j=1;j<=numprime&&(ll)i*prime[j]<maxn;j++){
vis[prime[j]*i]=1;
if(i%prime[j]==0){
mobi[i*prime[j]]=0;
break;
}
mobi[prime[j]*i]=-mobi[i];
}
}
}
void initfac(){
fac[0]=fac[1]=1;
for(ll i=2;i<maxn;i++)
fac[i]=fac[i-1]*i%mod;
inv_fac[maxn-1]=quick(fac[maxn-1],mod-2);
for(int i=maxn-2;i>=0;i--)
inv_fac[i]=inv_fac[i+1]*(i+1)%mod;
}
void initquick(){
fib[1]=fib[2]=1;
for(int i=3;i<maxn;i++)
fib[i]=(fib[i-1]+fib[i-2])%(mod-1);//快速幂降幂操作
}
int main(){
initmob(); initfac(); initquick();
int t;
cin>>t;
while(t--){
scanf("%lld%lld",&n,&k);
ll ans=0;
for(ll i=1;i<=n;i++){
if(n%i) continue;
ll tempans=0;
for(int j=i;j<=n;j+=i)
if(n%j==0){
tempans=(tempans+mobi[j/i]*C(n/j+k-1,k-1)+mod)%mod;
}
ans=(ans+tempans*(quick(2ll,fib[i]+mod-1)+mod-1))%mod;//快速幂降幂
}
ll tmp=C(n+k-1,k-1);
tmp=quick(tmp,(ll)mod-2);
printf("%lld\n",ans*tmp%mod);
}
return 0;
}