Description
Hint
- \(1\le t\le 10^5\)
- \(1\le n, f, b\le 2\times 10^3\)
Solution
首先,最高的 \(n\) 一定是两边可以看到的。然后整个状况一定是这样:
我们可以发现,左边的部分可以被分为 \(f - 1\) 组,每一组的开头都为该组一个最高的建筑,其他的由于根本看不见,所以可以随意排列。右边亦是如此。
有一个显而易见的结论: \(n\) 个元素的圆排列种数,与 \(n- 1\) 个元素的排列数相同。
于是可以这样理解: 将最高楼左右分别分为 \(f - 1, b - 1\) 组,每一组内部任意做圆排列 。
这就是 第一类斯特林数:
第一类斯特林数 \(\begin{bmatrix}n\\ k\end{bmatrix}\) 表示 \(n\) 个不同元素分为 \(k\) 个非空圆排列的方案数。
递推式: \(\begin{bmatrix}n\\ k\end{bmatrix} = \begin{bmatrix}n - 1\\ k-1\end{bmatrix} + (n-1)\begin{bmatrix}n-1\\ k\end{bmatrix}\)
然后在所有 \(f + b - 2\) 组中,选取 \(f - 1\) 个置于左侧,其余的组置于右侧,那么这就相当于 \(\large{{f + b - 2}\choose {f - 1}}\) 。
答案:\(\begin{bmatrix}n - 1\\ f + b - 2\end{bmatrix} \times \large{{f + b - 2}\choose {f - 1}}\)
复杂度:\(O(n^2 + t)\)。
Code
#include <iostream>
using namespace std;
const int N = 2e3 + 5;
const int mod = 1e9 + 7;
long long s[N][N];
long long c[N][N];
void init(int n = 2e3) {
s[0][0] = s[1][1] = 1ll;
for (register int i = 2; i <= n; i++)
for (register int j = 1; j <= i; j++)
s[i][j] = (s[i - 1][j - 1] + (i - 1) * s[i - 1][j]) % mod;
for (register int i = 0; i <= n; i++) {
c[i][0] = c[i][i] = 1ll;
for (register int j = 1; j < i; j++)
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
}
}
signed main() {
init();
int t; cin >> t;
while (t--) {
int n, f, b;
cin >> n >> f >> b;
if (f + b - 2 > n - 1) cout << 0 << endl;
else cout << s[n - 1][f + b - 2] * c[f + b - 2][f - 1] % mod << endl;
}
}