Description
将 n n n本书等概率随机放在 k k k层书架上,如果第 i i i层书架上有 c n t i cnt_i cnti本书,那么该层书架的稳定值为 s t a b l e i = f [ c n t i ] stable_i=f[cnt_i] stablei=f[cnti],其中 f [ 0 ] = 0 , f [ 1 ] = 1 , f [ i ] = f [ i − 1 ] + f [ i − 2 ] f[0]=0,f[1]=1,f[i]=f[i-1]+f[i-2] f[0]=0,f[1]=1,f[i]=f[i−1]+f[i−2]为斐波那契数列,美观度为 b e a u t y i = 2 s t a b l e i − 1 beauty_i=2^{stable_i}-1 beautyi=2stablei−1,此时得分为 g c d ( b e a u t y 1 , . . . , b e a u t y k ) gcd(beauty_1,...,beauty_k) gcd(beauty1,...,beautyk),求得分期望值
Input
第一行一整数 T T T表示用例组数,每组用例输入两个整数 n , k ( 1 ≤ T ≤ 10 , 0 < n , k ≤ 1 0 6 ) n,k(1\le T\le 10,0<n,k\le 10^6) n,k(1≤T≤10,0<n,k≤106)
Output
输出得分期望值,结果模 1 0 9 + 7 10^9+7 109+7
Sample Input
1
6 8
Sample Output
797202805
Solution
首先证明两个结论:
1. g c d ( 2 a − 1 , 2 b − 1 ) = 2 g c d ( a , b ) − 1 1.gcd(2^a-1,2^b-1)=2^{gcd(a,b)}-1 1.gcd(2a−1,2b−1)=2gcd(a,b)−1
假设 a ≥ b a\ge b a≥b,则有
g c d ( 2 a − 1 , 2 b − 1 ) = g c d ( 2 a − b ( 2 b − 1 ) + 2 a − b − 1 , 2 b − 1 ) = g c d ( 2 a − b − 1 , 2 b − 1 ) . . . = g c d ( 2 a % b − 1 , 2 b − 1 ) \begin{array}{rcl} gcd(2^a-1,2^b-1)&=&gcd(2^{a-b}(2^b-1)+2^{a-b}-1,2^b-1)\\ &=&gcd(2^{a-b}-1,2^b-1)\\ &...&\\ &=&gcd(2^{a\%b}-1,2^b-1) \end{array} gcd(2a−1,2b−1)==...=gcd(2a−b(2b−1)+2a−b−1,2b−1)gcd(2a−b−1,2b−1)gcd(2a%b−1,2b−1)
辗转相除即得结论.
2. g c d ( f a , f b ) = f g c d ( a , b ) 2.gcd(f_a,f_b)=f_{gcd(a,b)} 2.gcd(fa,fb)=fgcd(a,b)
首先注意到
g
c
d
(
f
x
,
f
x
−
1
)
=
g
c
d
(
f
x
−
1
+
f
x
−
2
,
f
x
−
1
)
=
g
c
d
(
f
x
−
1
,
f
x
−
2
)
=
.
.
.
=
g
c
d
(
f
1
,
f
2
)
=
1
gcd(f_x,f_{x-1})=gcd(f_{x-1}+f_{x-2},f_{x-1})=gcd(f_{x-1},f_{x-2})=...=gcd(f_1,f_2)=1
gcd(fx,fx−1)=gcd(fx−1+fx−2,fx−1)=gcd(fx−1,fx−2)=...=gcd(f1,f2)=1
假设
a
≥
b
a\ge b
a≥b,那么有
f
x
=
f
x
−
1
+
f
x
−
2
=
2
f
x
−
2
+
f
x
−
3
=
.
.
.
=
f
y
+
1
f
x
−
y
+
f
y
f
x
−
y
−
1
f_x=f_{x-1}+f_{x-2}=2f_{x-2}+f_{x-3}=...=f_{y+1}f_{x-y}+f_yf_{x-y-1}
fx=fx−1+fx−2=2fx−2+fx−3=...=fy+1fx−y+fyfx−y−1
则有
g
c
d
(
f
x
,
f
y
)
=
g
c
d
(
f
y
+
1
f
x
−
y
+
f
y
f
x
−
y
−
1
,
f
y
)
=
g
c
d
(
f
y
+
1
f
x
−
y
,
f
y
)
=
g
c
d
(
f
x
−
y
,
f
y
)
.
.
.
=
g
c
d
(
f
x
%
y
,
f
y
)
\begin{array}{rcl} gcd(f_x,f_y)&=&gcd(f_{y+1}f_{x-y}+f_yf_{x-y-1},f_y)\\ &=&gcd(f_{y+1}f_{x-y},f_y)\\ &=&gcd(f_{x-y},f_y)\\ &...&\\ &=&gcd(f_{x\%y},f_y) \end{array}
gcd(fx,fy)===...=gcd(fy+1fx−y+fyfx−y−1,fy)gcd(fy+1fx−y,fy)gcd(fx−y,fy)gcd(fx%y,fy)
辗转相除即得结论.
现在考虑原问题,由上面两个结论即得到当 k k k个书架上书的数量为 a 1 , . . . , a k a_1,...,a_k a1,...,ak时,其得分即为 2 f g c d ( a 1 , . . . , a k ) − 1 2^{f_{gcd(a_1,...,a_k)}}-1 2fgcd(a1,...,ak)−1,总方案数即为将 n n n本书放入 k k k个书架,方案数 C n + k − 1 k − 1 C_{n+k-1}^{k-1} Cn+k−1k−1,假设 g c d ( a 1 , . . . , a k ) = d , a 1 + . . . + a k = n gcd(a_1,...,a_k)=d,a_1+...+a_k=n gcd(a1,...,ak)=d,a1+...+ak=n的方案数有 g ( d ) g(d) g(d)种,那么答案即为 a n s = ∑ d ∣ n g ( d ) ( 2 f d − 1 ) ans=\sum\limits_{d|n}g(d)(2^{f_d}-1) ans=d∣n∑g(d)(2fd−1),故只要求出 g ( 1 ) , . . . , g ( d ) g(1),...,g(d) g(1),...,g(d)即可
令 d ∣ g c d ( a 1 , . . . , a k ) , a 1 + . . . + a k = n d|gcd(a_1,...,a_k),a_1+...+a_k=n d∣gcd(a1,...,ak),a1+...+ak=n的方案数为 F ( d ) F(d) F(d),由插板法知 F ( d ) = C n d + k − 1 k − 1 F(d)=C_{\frac{n}{d}+k-1}^{k-1} F(d)=Cdn+k−1k−1
而 F ( d ) = ∑ d ∣ i g ( i ) F(d)=\sum\limits_{d|i}g(i) F(d)=d∣i∑g(i),由莫比乌斯反演有 g ( d ) = ∑ d ∣ i μ ( i d ) F ( i ) g(d)=\sum\limits_{d|i}\mu(\frac{i}{d})F(i) g(d)=d∣i∑μ(di)F(i),预处理莫比乌斯函数后直接求解即可
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 1000005
typedef long long ll;
int prime[maxn],mu[maxn],check[maxn],tot;
void Moblus(int n=1e6)
{
memset(check,0,sizeof(check));
mu[1]=1;
tot=0;
for(int i=2;i<=n;i++)
{
if(!check[i])
{
prime[tot++]=i;
mu[i]=-1;
}
for(int j=0;j<tot&&i*prime[j]<=n;j++)
{
check[i*prime[j]]=1;
if(i%prime[j]==0)
{
mu[i*prime[j]]=0;
break;
}
mu[i*prime[j]]=-mu[i];
}
}
}
#define mod 1000000007
int mul(int x,int y)
{
ll z=1ll*x*y;
return z-z/mod*mod;
}
int add(int x,int y)
{
x+=y;
if(x>=mod)x-=mod;
return x;
}
int Pow(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)ans=mul(ans,a);
a=mul(a,a);
b>>=1;
}
return ans;
}
int a[maxn],fact[2*maxn],inv[2*maxn];
void init(int n=1e6)
{
Moblus();
a[0]=0,a[1]=1;
for(int i=2;i<=1e6;i++)a[i]=(a[i-2]+a[i-1])%(mod-1);
for(int i=1;i<=1e6;i++)a[i]=add(Pow(2,a[i]),mod-1);
fact[0]=1;
for(int i=1;i<=2*n;i++)fact[i]=mul(i,fact[i-1]);
inv[1]=1;
for(int i=2;i<=2*n;i++)inv[i]=mul(mod-mod/i,inv[mod%i]);
inv[0]=1;
for(int i=1;i<=2*n;i++)inv[i]=mul(inv[i],inv[i-1]);
}
int C(int n,int m)
{
if(m<0||m>n)return 0;
return mul(fact[n],mul(inv[m],inv[n-m]));
}
int F(int d,int k)
{
return C(d+k-1,k-1);
}
int main()
{
init();
int T,n,k;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
int ans=0;
for(int d=1;d<=n;d++)
if(n%d==0)
{
int f=0;
for(int i=d;i<=n;i+=d)
if(n%i==0)
{
if(mu[i/d]==1)f=add(f,F(n/i,k));
else if(mu[i/d]==-1)f=add(f,mod-F(n/i,k));
}
ans=add(ans,mul(f,a[d]));
}
printf("%d\n",mul(ans,Pow(C(n+k-1,k-1),mod-2)));
}
return 0;
}