1. 程式人生 > 其它 >【AGC040C】Neither AB nor BA

【AGC040C】Neither AB nor BA

題目

題目連結:https://atcoder.jp/contests/agc040/tasks/agc040_c
給定一個 \(n\),求有多少個長度為 \(n\) 且只包含 ABC 的字串滿足以下條件:

  • 每次可以選定一個長度為 \(2\) 的子串刪掉,且這個子串不為 ABBA,直到整個字串被刪除。

\(n\leq 10^7\)\(n\) 是偶數。

思路

對於一個合法的字串 \(s\),把它偶數位置上的字元 AB 全部取反,這樣原問題等價於在新串上每次刪除長度為 \(2\) 的子串且不為 AABB。因為每一個合法字串之間都是一一對應的。
那麼新問題只需要滿足這個字串 AB 的出現次數不超過嚴格一半即可。容斥一下直接隨便計數就好了。
時間複雜度 \(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;
}