[AGC040C] Neither AB nor BA

算法

容斥.

思路

借用这里的 Trick 2, 我们将所有偶数位的 \(B \rightarrow A\) , \(A \rightarrow B\).
那么原问题的限制就转化为: 不能删相邻的 \(AA\)\(BB\) , 求最终可以删空的方案数.

考虑这个限制的充要条件是什么.
对于每一段连续的 \(A(B)\), 我们可以在左右两端找到字符并合法删去, 如果 \(A(B)\) 的总数大于 \(\frac{n}{2}\), 那么最后就不能够删空, 也就是非法的.
所以充要条件即为: \(A,\ B\) 的数量均不大于 \(\frac{n}{2}\).

接下来就是容斥的计算了, 总方案数是 \(3^n\), 不合法的方案数是 \(2 \times \sum_{i = \frac{n}{2} + 1}^n \binom{n}{i} 2^{n - i}\).

复制代码
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
#include "iostream" using namespace std; constexpr int N = 1e7 + 1, mod = 998244353; #define int long long int n; int fac[N], inv[N]; int qpow(int x, int y = mod - 2) { int ret = 1; while (y) { if (y & 1) ret = ret * x % mod; x = x * x % mod; y >>= 1; } return ret; } void init() { cin >> n; fac[0] = 1; for (int i = 1; i <= n; ++i) fac[i] = i * fac[i - 1] % mod; inv[n] = qpow(fac[n]); for (int i = n - 1; ~i; --i) inv[i] = (i + 1) * inv[i + 1] % mod; } int get(int x, int y) { return (y < 0 or y > x or x < 0) ? 0 : (fac[x] * inv[y] % mod * inv[x - y] % mod); } void calculate() { int ans = qpow(3, n); for (int i = n / 2 + 1; i <= n; ++i) ans = (ans - 2 * qpow(2, n - i) * get(n, i) + mod) % mod; cout << ans << '\n'; } void solve() { init(); calculate(); } signed main() { solve(); return 0; }
posted @   Steven1013  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开