【AGC040C】Neither AB nor BA
阿新 • • 發佈:2021-07-15
題目
題目連結:https://atcoder.jp/contests/agc040/tasks/agc040_c
給定一個 \(n\),求有多少個長度為 \(n\) 且只包含 ABC
的字串滿足以下條件:
- 每次可以選定一個長度為 \(2\) 的子串刪掉,且這個子串不為
AB
或BA
,直到整個字串被刪除。
\(n\leq 10^7\) 且 \(n\) 是偶數。
思路
對於一個合法的字串 \(s\),把它偶數位置上的字元 AB
全部取反,這樣原問題等價於在新串上每次刪除長度為 \(2\) 的子串且不為 AA
或 BB
。因為每一個合法字串之間都是一一對應的。
那麼新問題只需要滿足這個字串 A
和 B
的出現次數不超過嚴格一半即可。容斥一下直接隨便計數就好了。
時間複雜度 \(O(n)\)
程式碼
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int N=10000010,MOD=998244353; int n; ll ans,fac[N],inv[N]; ll fpow(ll x,ll k) { ll ans=1; for (;k;k>>=1,x=x*x%MOD) if (k&1) ans=ans*x%MOD; return ans; } ll C(int n,int m) { return fac[n]*inv[m]%MOD*inv[n-m]%MOD; } int main() { scanf("%d",&n); fac[0]=inv[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD; inv[n]=fpow(fac[n],MOD-2); for (int i=n-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%MOD; ans=fpow(3,n); for (int i=n/2+1;i<=n;i++) ans=(ans-2LL*C(n,i)*fpow(2,n-i))%MOD; cout<<(ans%MOD+MOD)%MOD; return 0; }