题面:https://www.luogu.org/problemnew/show/P4609
考虑先把最大值放了以后,左边a-1个圆排列,右边b-1个圆排列。
直接就是C(a-1+b-1,a-1)*S(n-1,a-1+b-1)。
S为第一类斯特林数。
#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#define N 55000
#define M 220
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline ll read()
{
char ch=0;
ll x=0,flag=1;
while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*flag;
}
const ll mo=1e9+7;
ll fac[N],vac[N],s[N][M];
ll c(ll n,ll m){return fac[n]*vac[m]%mo*vac[n-m]%mo;}
ll ksm(ll x,ll k){ll ans=1;while(k){if(k&1)ans=ans*x%mo;k>>=1;x=x*x%mo;}return ans;}
void work()
{
ll n=read(),a=read(),b=read();
if(a+b>n+1)printf("0\n");
else printf("%lld\n",(c(a-1+b-1,a-1)*s[n-1][a-1+b-1])%mo);
}
int main()
{
fac[0]=vac[0]=s[0][0]=1;
for(ll i=1;i<=50000;i++)
{
fac[i]=fac[i-1]*i%mo;
vac[i]=vac[i-1]*ksm(i,mo-2)%mo;
for(ll j=1;j<=200;j++)
s[i][j]=((s[i-1][j]*(i-1)%mo)+s[i-1][j-1])%mo;
}
ll t=read();
for(ll i=1;i<=t;i++)work();
return 0;
}