题目来源: AT5661 [AGC040C] Neither AB nor BA.
参考题解: Tea’s blog
LXD让我们做这个题目,当然先是手玩啦,找删的掉得太多,所以找删不掉得。n=2:AB BA ,n=4 前面补,后面补等等写了写式子,发现在删不掉得基础上补了,前面得又被删掉了,无头绪,抄题解啦。
题解很巧妙,处理AB的在奇偶位置上的个数关系。成功的将题目转为数学题!
我们可以发现,将一个字串的A替换为B,B替换为A,性质不变,因此可以只处理一半。
我们设奇数位置上的A有
x
x
x个,偶数位置上的B有
y
y
y个,则有
{
x
<
=
n
2
y
<
=
n
2
\begin{cases} x<=\frac {n}{2}\\ y<=\frac n2 \end{cases}
{x<=2ny<=2n
偶数位置上的非B符号,也就是A和C有
n
2
−
y
\frac n2-y
2n−y个,每个非B都可以删掉一个奇数位置上的A,如果删完了有剩下的,那必然有奇数位置上的A和偶数位置上的B相邻,什么时候才能有剩下的?也即是
x
>
=
n
2
−
y
x>=\frac n2-y
x>=2n−y;移向后得
x
+
y
>
=
n
2
x+y>=\frac n2
x+y>=2n.
因此我们找出所有情况减去删不掉的情况也即是:
3
n
−
2
∗
c
o
u
n
t
(
(
x
+
y
)
>
n
2
)
3^n-2*count((x+y)>\frac n2)
3n−2∗count((x+y)>2n)
如何计算: c o u n t ( ( x + y ) ) count((x+y)) count((x+y))?
分为两部分:
- 奇A偶B无关的数据
设 x + y = t x+y=t x+y=t,则奇A偶B无关的数据有 n − t n-t n−t个,在奇数位置上可填的数据是B,C,在偶数位置上可以填的数据是A,C,各有两种情况,因此总数是 2 n − t 2^{n-t} 2n−t; - 奇A偶B数据
也就是从n个数里选出t个数,其中奇数有 x x x个,偶数有 y y y个。
开始我是这么想的
例如: n = 6 , t = 4 n=6,t=4 n=6,t=4的情况:
{ x = 1 , y = 3 ; C 3 1 ∗ C 3 3 x = 2 , y = 2 ; C 2 2 ∗ C 2 2 x = 3 , y = 1 ; C 3 3 ∗ C 3 1 \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} ⎩⎪⎨⎪⎧x=1,y=3;C31∗C33x=2,y=2;C22∗C22x=3,y=1;C33∗C31
计算完了之后发现是3+3*3+3=15,正好是 C 6 4 C^4_6 C64,也就是我们只需要从 n n n中选出 t t t个数,也就是 C n t C^t_n Cnt。其中奇数的位置放上A,偶数的位置放上B,这样就符合要求了。
因此删不完得字串个数就是: C n t ∗ 2 n − t C^t_n*2^{n-t} Cnt∗2n−t
如何计算: c o u n t ( ( x + y ) > n 2 ) count((x+y)>\frac n2) count((x+y)>2n)?
∑ t = n 2 + 1 n ∗ C n t ∗ 2 n − t \sum_{t=\frac n2+1}^{n}*C^t_n*2^{n-t} ∑t=2n+1n∗Cnt∗2n−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);
}