hdu5894 hannnnah_j’s Biological Test(組合數取模)

題意:ios

n個桌子圍成圈m我的,間隔至少k個桌子,問方案數git

思路:spa

這能夠推出來一個公式C(n-m*k-1,m-1),而後第一我的有n中選擇,每一個人是相等的code

因此就*n/m就行了,除改爲乘逆元就行了blog

/* ***********************************************
Author        :devil
************************************************ */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <string>
#include <cmath>
#include <stdlib.h>
#define inf 0x3f3f3f3f
#define LL long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ou(a) printf("%d\n",a)
#define pb push_back
#define mkp make_pair
template<class T>inline void rd(T &x){char c=getchar();x=0;while(!isdigit(c))c=getchar();while(isdigit(c)){x=x*10+c-'0';c=getchar();}}
#define IN freopen("in.txt","r",stdin);
#define OUT freopen("out.txt","w",stdout);
using namespace std;
const int mod=1e9+7;
const int N=1e6+10;
int f[N];
int inv(int x)
{
    int ret=1,y=mod-2;
    while(y)
    {
        if(y&1)ret=1ll*ret*x%mod;
        y>>=1;
        x=1ll*x*x%mod;
    }
    return ret;
}
int C(int n,int m)
{
    if(n<m) return 0;
    int ret=1ll*f[n]*inv(f[m])%mod;
    ret=1ll*ret*inv(f[n-m])%mod;
    return ret;
}
int lucas(int n,int m)
{
    if(!m) return 1;
    return 1ll*C(n%mod,m%mod)*lucas(n/mod,m/mod)%mod;
}
void init()
{
    f[0]=1;
    for(int i=1;i<=N-10;i++) f[i]=1ll*i*f[i-1]%mod;
}
int main()
{
    init();
    int t;
    rd(t);
    LL n,m,k;
    while(t--)
    {
        rd(n),rd(m),rd(k);
        if(m>1&&n<m*(k+1))
        {
            printf("0\n");
            continue;
        }
        printf("%lld\n",((lucas(n-m*k-1,m-1)*n)%mod*inv(m))%mod);
    }
    return 0;
}
相關文章
相關標籤/搜索