Problem Description
Patrick Star bought a bookshelf, he named it ZYG !!
Patrick Star has N book .
The ZYG has K layers (count from 1 to K) and there is no limit on the capacity of each layer !
Now Patrick want to put all N books on ZYG :
1. Assume that the i-th layer has cnti(0≤cnti≤N) books finally.
2. Assume that f[i] is the i-th fibonacci number (f[0]=0,f[1]=1,f[2]=1,f[i]=f[i−2]+f[i−1]).
3. Define the stable value of i-th layers stablei=f[cnti].
4. Define the beauty value of i-th layers beautyi=2stablei−1.
5. Define the whole beauty value of ZYG score=gcd(beauty1,beauty2,...,beautyk)(Note: gcd(0,x)=x).
Patrick Star wants to know the expected value of score if Patrick choose a distribute method randomly !
Input
The first line contain a integer T (no morn than 10), the following is T test case, for each test case :
Each line contains contains three integer n,k(0<n,k≤106).
Output
For each test case, output the answer as a value of a rational number modulo 109+7.
Formally, it is guaranteed that under given constraints the probability is always a rational number pq (p and q are integer and coprime, q is positive), such that q is not divisible by 109+7. Output such integer a between 0 and 109+6 that p−aq is divisible by 109+7.
Sample Input
1 6 8
Sample Output
797202805
这道题还是蛮好的,把 欧拉降幂+容斥定理(莫比乌斯)+数论知识
题意: 告诉我们有K个桶,一共n个球,把这n个球放到 这k 个桶中,然后定义一个魅力值,让我们求期望。魅力值是
所有层的gcd(), 然后魅力值就是
前置技能:1.
2.
上述两式都可以推广到n个
首先考虑两个桶里面的球,分别为和,对于这两层的魅力值为,也就是 ; 所以推广到k个桶,就是 , 枚举所有的方案是不可能的,所以我们考虑枚举这个 , 的取指最多只有n个,我们是存在枚举的可能的。
直接考虑 ,不好考虑,我们可以考虑 的倍数,然后容斥定理计算一下
然后就是莫比乌斯反演的基本操作了
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i=a;i<b;i++)
#define per(i,a,b) for(int i=b-1;i>=a;i--)
const int mod=1e9+7;
const int inv_mod=1e9+6;
const int N=2e6+10;
//begin
int prime[N],mu[N];
bool check[N];
void Mobius(int N){
mu[1] = 1;
int tot = 0;
for(int i=2;i<N;i++){
if(!check[i]){
prime[tot ++] = i;
mu[i] = -1;
}
for(int j=0;j<tot;j++){
if(1LL*i * prime[j] >=1LL*N)break;
check[1ll*i * prime[j]] = true;
if(i % prime[j] == 0){
mu[i * prime[j]] = 0;
break;
}else{
mu[i * prime[j]] = -mu[i];
}
}
}
}
//end
//对于n和m比较小的情况下,C(n,m)的复杂度可以预处理到O(1)
//begin
LL pow_mod(LL base,int n,int mod){
LL ans=1;
while(n){
if(n&1)ans=(ans*base)%mod;
base=(base*base)%mod;
n>>=1;
}
return ans%mod;
}
int F[2*N],inv_F[2*N];
void init_C_small(int N){
F[0]=1;
rep(i,1,N) F[i]=1LL*i*F[i-1]%mod;
inv_F[N-1]=pow_mod(F[N-1],mod-2,mod);
per(i,0,N-1)inv_F[i]=1LL*inv_F[i+1]*(i+1)%mod;//invF[i]*i!=1,invF[i+1]*i!*(i+1)=1
}
LL C(int n, int m) {
if(n < 0 || m < 0 || m > n) return 0;
if(m == 0 || m == n) return 1;
return 1LL*F[n] * inv_F[n - m] % mod * inv_F[m] % mod;
}
//end
int fib[N];
void init(){
Mobius(N);
init_C_small(2*N);
fib[1]=fib[2]=1;
for(int i=3;i<N;i++)fib[i]=(1LL*fib[i-1]+1LL*fib[i-2])%inv_mod;
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
int n,k;
scanf("%d %d",&n,&k);
LL ans=0;
for(int i=1;i<=n;++i){
if(n%i)continue;
LL tmp=0;
for(int j=i;j<=n;j+=i){
if(n%j)continue;
tmp=(tmp+1LL*mu[j/i]*C(n/j+k-1,k-1)%mod+mod)%mod;
}
ans=(ans+tmp*(pow_mod(2LL,fib[i],mod)-1+mod)%mod+mod)%mod;
}
LL ans2=C(n+k-1,k-1);
//printf("ans1:%lld ans2:%lld\n",ans,ans2);
ans=ans*pow_mod(ans2,mod-2,mod)%mod;
printf("%lld\n",ans);
}
return 0;
}