hdu6363(杭电多校第六场2)容斥、数学公式

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的方案数为C_{n+k-1}^{k-1}

则每种gcd情况的方案数为C_{\frac{n}{gcd}+k-1}^{k-1},这其中包含重复,如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);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_25576697/article/details/81570340