題目來源: AT5661 [AGC040C] Neither AB nor BA.
參考題解: Tea’s blog
LXD讓我們做這個題目,當然先是手玩啦,找刪的掉得太多,所以找刪不掉得。n=2:AB BA ,n=4 前面補,後面補等等寫了寫式子,發現在刪不掉得基礎上補了,前面得又被刪掉了,無頭緒,抄題解啦。
題解很巧妙,處理AB的在奇偶位置上的個數關係。成功的將題目轉爲數學題!
我們可以發現,將一個字串的A替換爲B,B替換爲A,性質不變,因此可以只處理一半。
我們設奇數位置上的A有個,偶數位置上的B有個,則有
偶數位置上的非B符號,也就是A和C有個,每個非B都可以刪掉一個奇數位置上的A,如果刪完了有剩下的,那必然有奇數位置上的A和偶數位置上的B相鄰,什麼時候纔能有剩下的?也即是;移向後得.
因此我們找出所有情況減去刪不掉的情況也即是:
如何計算:?
分爲兩部分:
- 奇A偶B無關的數據
設,則奇A偶B無關的數據有個,在奇數位置上可填的數據是B,C,在偶數位置上可以填的數據是A,C,各有兩種情況,因此總數是; - 奇A偶B數據
也就是從n個數裏選出t個數,其中奇數有個,偶數有個。
開始我是這麼想的
例如:的情況:
計算完了之後發現是3+3*3+3=15,正好是,也就是我們只需要從中選出個數,也就是。其中奇數的位置放上A,偶數的位置放上B,這樣就符合要求了。
因此刪不完得字串個數就是:
如何計算:?
到這裏我自己就理清思路了。順便複習了下markdown,但我過會又會忘記的——已經18歲的老年癡呆患者!
//TJ
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+10;
typedef long long ll;
ll n,fac[N],invf[N],mi2[N],ans;//fac 階乘,invf 階乘得逆元
const ll mod=998244353;
ll qpow(ll a,ll b) {
ll ans=1ll;
while(b) {
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b/=2;
}
return ans;
}
ll C(int x,int y) {
return fac[x]*invf[y]%mod*invf[x-y]%mod;
}
int main() {
scanf("%d",&n);
fac[0]=mi2[0]=1;
for(int i=1; i<=n; i++)
fac[i]=1ll*fac[i-1]*i%mod,mi2[i]=mi2[i-1]*2%mod;//fac階乘,ci 2^2;
invf[n]=qpow(fac[n],mod-2);
for(int i=n-1; i>=0; i--)
invf[i]=1ll*invf[i+1]*(i+1)%mod;
for(int i=n/2+1; i<=n; i++)
ans=(ans+C(n,i)*mi2[n-i]%mod)%mod;
ans=((qpow(3,n)-ans*2)%mod+mod)%mod;
printf("%lld\n",ans);
}