AT5661 [AGC040C] Neither AB nor BA:數論,組合數學

題目來源: AT5661 [AGC040C] Neither AB nor BA.
參考題解: Tea’s blog
LXD讓我們做這個題目,當然先是手玩啦,找刪的掉得太多,所以找刪不掉得。n=2:AB BA ,n=4 前面補,後面補等等寫了寫式子,發現在刪不掉得基礎上補了,前面得又被刪掉了,無頭緒,抄題解啦。
題解很巧妙,處理AB的在奇偶位置上的個數關係。成功的將題目轉爲數學題!
我們可以發現,將一個字串的A替換爲B,B替換爲A,性質不變,因此可以只處理一半。
我們設奇數位置上的A有xx個,偶數位置上的B有yy個,則有
{x<=n2y<=n2 \begin{cases} x<=\frac {n}{2}\\ y<=\frac n2 \end{cases}
偶數位置上的非B符號,也就是A和C有n2y\frac n2-y個,每個非B都可以刪掉一個奇數位置上的A,如果刪完了有剩下的,那必然有奇數位置上的A和偶數位置上的B相鄰,什麼時候纔能有剩下的?也即是x>=n2yx>=\frac n2-y;移向後得x+y>=n2x+y>=\frac n2.
因此我們找出所有情況減去刪不掉的情況也即是:
3n2count((x+y)>n2)3^n-2*count((x+y)>\frac n2)

如何計算:count((x+y))count((x+y))

分爲兩部分:

  • 奇A偶B無關的數據
    x+y=tx+y=t,則奇A偶B無關的數據有ntn-t個,在奇數位置上可填的數據是B,C,在偶數位置上可以填的數據是A,C,各有兩種情況,因此總數是2nt2^{n-t};
  • 奇A偶B數據
    也就是從n個數裏選出t個數,其中奇數有xx個,偶數有yy個。
    開始我是這麼想的
    例如:n=6,t=4n=6,t=4的情況:
    {x=1,y=3;C31C33x=2,y=2;C22C22x=3,y=1;C33C31\begin{cases}x=1,y=3;C^1_3*C^3_3 \\x=2,y=2;C^2_2*C^2_2\\x=3,y=1;C^3_3*C^1_3\end{cases}
    計算完了之後發現是3+3*3+3=15,正好是C64C^4_6,也就是我們只需要從nn中選出tt個數,也就是CntC^t_n。其中奇數的位置放上A,偶數的位置放上B,這樣就符合要求了。
    因此刪不完得字串個數就是: Cnt2ntC^t_n*2^{n-t}

如何計算:count((x+y)>n2)count((x+y)>\frac n2)

t=n2+1nCnt2nt\sum_{t=\frac n2+1}^{n}*C^t_n*2^{n-t}

到這裏我自己就理清思路了。順便複習了下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);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章