Description
nn个不同的位置围成一圈,要给安排个座位给孩子坐,要求任意两个孩子之间空座位数量不小于kk,问方案数
Input
第一行一整数表示用例组数,每组用例输入三个整数n,m,k(T≤1000,0<m<n<106,0<k<1000)n,m,k(T≤1000,0<m<n<106,0<k<1000)
Output
对于每组用例,输出方案数,结果模109+7109+7
Sample Input
2
4 2 6
5 2 1
Sample Output
0
5
Solution
若m=1m=1,只有一个孩子随便坐,方案数nn
若,给孩子编号,最后除以m!m!即可取消编号带来的影响,首先以第11个孩子的位置为起点把圈变成序列,由于任意两个孩子之间空座位不少于,不妨先拿出kmkm个座位空着,对于剩下的n−km−1n−km−1个座位和m−1m−1个孩子,随便坐即可,方案数Am−1n−km−1An−km−1m−1,第一个孩子选座位有nn种方案,故方案数为
Code
#include<cstdio>
using namespace std;
typedef long long ll;
#define maxn 1111111
ll inv[maxn];
#define mod 1000000007ll
int T,n,m,k;
ll mod_pow(ll a,ll b)
{
ll ans=1ll;
while(b)
{
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
ll C(int n,int m)
{
if(n<m)return 0;
if(n-m>m)m=n-m;
ll ans=1ll;
for(int i=1;i<=n-m;i++)ans=ans*(i+m)%mod*inv[i]%mod;
return ans;
}
int main()
{
for(int i=1;i<maxn;i++)inv[i]=mod_pow(i,mod-2);
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&k);
if(m==1)printf("%d\n",n);
else printf("%I64d\n",1ll*n*C(n-1-k*m,m-1)%mod*inv[m]%mod);
}
return 0;
}