P4609 建筑师 Sol

首先显然可以确定一个最高的建筑,以此为中心,分成左半和右半。
同时可以认为,左半分为了 \(A-1\) 个段,右半为 \(B-1\)
然后可以将一个可以被看见的建筑理解为一个以其为开头的段。
那么这一段中以其为开头,其余的可以随便排序。
计算答案发现,假设某一段长度为 \(x\),则排列方案数为 \(P_{x-1}^{x-1}\)
而一个大小为 \(x\) 的环,排列方案数也恰好为 \(\dfrac{P_x^x}{x}=P_{x-1}^{x-1}\)

则可以理解为将 \(n-1\) 个元素分为 \(A+B-2\) 个环。

那么答案就是这样,左边右边分一下,一个组合数,然后分一下环,乘起来。

答案即为 \(S_1(n-1, A+B-1)\times\dbinom{A+B-2}{A-1}\)

res 表示第一类斯特林数,c 表示组合数。

inline void init() {
  res[0][0] = 1;
  for (int j = 1; j <= 5e4; ++j)
    for (int i = 1; i <= 2e2; ++i)
      res[j][i] = (res[j-1][i-1] + (j - 1) * res[j-1][i]) % p;
  for (int i = 0; i <= 2e2; ++i) c[0][i] = 1;
  for (int i = 1; i <= 2e2; ++i)
    for (int j = 1; j <= 2e2; ++j)
      c[i][j] = (c[i-1][j-1] + c[i][j-1]) % p;
}

inline void query() {
  cin >> n >> a >> b;
  int ans = res[n-1][a+b-2] * c[a-1][a+b-2];
  cout << ans % p << endl;
}
posted @ 2022-07-18 17:05  MistZero  阅读(29)  评论(0编辑  收藏  举报