首先注意到 (n) 这个高度很特殊,因为它是左边看到的最后一个建筑,也是右边看到的最后一个建筑,也就是说,它是分界点。
(n) 左边有 (A-1) 分割点,每一段都是递减的,最高的那个是开头,也就是分割点。
这样就能满足从左往右看到 (A) 个高度了。
右边同理。
发现我们可以直接用第一类斯特林数的定义了!!!
答案就是把 (n-1) 划分成 (A+B-2) 个循环的方案,其中 (n) 因为没法动被去除了。
因为对于每一个循环只有一种高度排列合法(即最高的放最后或者最前),而循环也恰好会被统计一次,也就是说这两个东西是一一对应的。
(A+B-2) 个循环还要选 (A-1) 个放到 (n) 左边,所以还得乘组合数。
那么答案就是
[egin{bmatrix}n-1\A+B-2end{bmatrix}inom{A+B-2}{A-1}
]
所以这题唯一的考点对于第一类斯特林数的熟练程度。
int S1[50005][205],fac[205],ifc[205];
#define mod 1000000007
inline int qpow(int n,int k){int res=1;for(;k;k>>=1,n=1ll*n*n%mod)if(k&1)res=1ll*n*res%mod;return res;}
int comb(int n,int m){return n<m?0:1ll*fac[n]*1ll*ifc[m]%mod*ifc[n-m]%mod;}
void init(){
fac[0]=1;rep(i,1,200)fac[i]=1ll*fac[i-1]*i%mod;
ifc[200]=qpow(fac[200],mod-2);per(i,199,0)ifc[i]=1ll*ifc[i+1]*(i+1)%mod;
S1[0][0]=1;rep(i,1,50000)rep(j,1,200)S1[i][j]=(S1[i-1][j-1]+1ll*S1[i-1][j]*(i-1)%mod)%mod;
}
signed main(){
init();
for(int T=read();T;--T){
int n=read(),A=read(),B=read();
if(A+B-1>n)puts("0");
else printf("%lld
",1ll*comb(A+B-2,A-1)*S1[n-1][A+B-2]%mod);
}
return 0;
}