bookshelf
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 449 Accepted Submission(s): 207
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
题意:有n本书,书架有k层,现在把书放到书架上,书架的score定义如题中所述,求书架score的期望值。
思路:有两个重要结论
1.gcd(a ^ x - 1,a ^ y - 1) = a ^ gcd(x,y) - 1
2.gcd(fib[x],fib[y]) = fib[gcd(x,y)]
处理化简后答案就为求2^fib[gcd(x1,x2,...,xk)]-1(x1+x2+...+xk==n)的期望,采用隔板法可知x1+x2+...+xk=n的方案数为,
则每种gcd情况的方案数为,这其中包含重复,如gcd==4的情况包含gcd==2的情况,简单容斥一下就可以。每个gcd的结果乘以各自方案数之和最后除以总的方案数就是答案。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2e6+10;
const ll mod = 1e9+7;
ll fib[maxn];
ll inv[maxn],fac[maxn],invf[maxn];
int yz[maxn];
ll ans[maxn];
ll quick_pow(ll a,ll b)
{
ll ans = 1;
while(b)
{
if(b&1)ans = (ans * a)%mod;
b>>=1;
a = (a*a)%mod;
}
return ans;
}
void init()
{
fib[0]=0;
fib[1]=1;
fib[2]=1;
for(int i=3;i<maxn;i++)fib[i]=(fib[i-1]+fib[i-2])%(mod-1);
inv[1]=1;
for (int i=2;i<maxn;i++)
inv[i]=((mod-mod/i)*inv[mod%i])%mod;
fac[0] = 1;
for(int i = 1;i<maxn;i++)
fac[i] = (fac[i-1] * (ll)i)%mod;
invf[0] = 1;
for(int i = 1;i<maxn;i++)
invf[i] = (invf[i-1]*inv[i])%mod;
}
int main()
{
int n,k;
init();
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
int tmp = n;
int cnt = 0;
for(int i = 1;i<=tmp;i++)
{
if(tmp%i==0)yz[cnt++]=i;
}
for(int i =0;i<cnt;i++)
{
ans[i] = ((fac[n/yz[i]+k-1]*invf[k-1])%mod*invf[n/yz[i]])%mod;
}
for(int i=cnt-2;i>=0;i--)
{
for(int j = i+1;j<cnt;j++)
{
if(yz[j]%yz[i]==0)
{
ans[i]=(ans[i]-ans[j]+mod)%mod;
}
}
}
ll res = 0;
for(int i = 0;i<cnt;i++)
{
res=(res+(ans[i]*(quick_pow(2,fib[yz[i]])-1+mod)%mod)%mod)%mod;
}
ll dx = ((fac[n+k-1]*invf[k-1])%mod*invf[n])%mod;
dx = quick_pow(dx,mod - 2);
printf("%lld\n",(res*dx)%mod);
}
}