hdu5894 hannnnah_j’s Biological Test(组合数取模)
题意:
n个桌子围成圈m个人,间隔至少k个桌子,问方案数
思路:
这可以推出来一个公式C(n-m*k-1,m-1),然后第一个人有n中选择,每个人是相等的
所以就*n/m就好了,除改成乘逆元就好了
/* *********************************************** 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; }