@atcoder - AGC040C@ Neither AB nor BA


@description@

給定偶數 N,求由 'A', 'B', 'C' 三種字符組成的字符串 S,有多少知足以下的條件:ip

每次能夠選擇 S 中的兩個相鄰字符(不能選擇 "AB" 與 "BA"),刪除它們。最後能夠將 S 刪成空串。字符串

好比:"ABBC" -> "AC" -> ""。因此 "ABBC" 對於 N = 4 時是合法的。it

將最終答案 mod 998244353。io

Constraints
2≤N≤10^7, 並保證 N 爲偶數class

Input
輸入形式以下:
N移動

Output
輸出答案 mod 998244353。di

Sample Input 1
2
Sample Output 1
7while

除了 "AB", "BA" 均可行。co

@solution@

考慮刪除連續 2 個字符,哪些東西不會變化。
這時你會驚訝地發現:一個字符在字符串中的所處位置的奇偶性不會變化。
其實挺容易驗證。假如在刪除的前面,不會影響;假如在刪除的後面,位置向前移動 2,奇偶不變。

那麼一個奇數位置上的 "A" 與一個偶數位置上的 "B" 永遠不可能互相消;一個偶數位置上的 "B" 與一個奇數位置上的 "A" 也永遠不可能互相消。這些字符須要其餘的字符消掉。
記 S1 = 奇數位置的 "A" 數量 + 偶數位置的 "B" 數量,那麼應有 2*S1 <= N。
同理記 S2 = 奇數位置的 "B" 數量 + 偶數位置的 "A" 數量,那麼應有 2*S2 <= N。

其實以上兩個條件 (2*S1 <= N, 2*S2 <= N) 就是充要條件。
能夠概括驗證。假如 2*S1 = N, 2*S2 = N 同時知足,則咱們能夠同時消 S1 與 S2;不然我老是消 S1 與 S2 的較大值。

那麼最終答案就是 3^N - (2*S1 > N 的方案數) - (2*S2 > N 的方案數)。
隨便組合計數一下就沒了。

@accepted code@

#include <cstdio>
const int MOD = 998244353;
const int MAXN = 10000000;
int sub(int x, int y) {return x - y < 0 ? x - y + MOD : x - y;}
int pow_mod(int b, int p) {
    int ret = 1;
    while( p ) {
        if( p & 1 ) ret = 1LL*ret*b%MOD;
        b = 1LL*b*b%MOD;
        p >>= 1;
    }
    return ret;
}
int pw2[MAXN + 5], fct[MAXN + 5], ifct[MAXN + 5];
void init() {
    pw2[0] = 1;
    for(int i=1;i<=MAXN;i++)
        pw2[i] = 2LL*pw2[i-1]%MOD;
    fct[0] = 1;
    for(int i=1;i<=MAXN;i++)
        fct[i] = 1LL*fct[i-1]*i%MOD;
    ifct[MAXN] = pow_mod(fct[MAXN], MOD-2);
    for(int i=MAXN-1;i>=0;i--)
        ifct[i] = 1LL*ifct[i+1]*(i+1)%MOD;
}
int comb(int n, int m) {
    return 1LL*fct[n]*ifct[m]%MOD*ifct[n-m]%MOD;
}
int main() {
    init(); int N;
    scanf("%d", &N);
    int ans = pow_mod(3, N);
    for(int i=N/2+1;i<=N;i++)
        ans = sub(ans, 2LL*comb(N, i)*pw2[N-i]%MOD);
    printf("%d\n", ans);
}

@detail@

老年選手連 AGC 的 C 題都作不出來了 QAQ。
整了一個上午 + 一個晚上,最後仍是看了題解 QAQ。

感受主要是。。。想不到根據位置的奇偶性來分析吧。。。
吃一塹,長一智.jpg。

爲何 AGC 這麼喜歡出這種類型的題啊 QAQ。 人類智慧實在是太強大了 QAQ。

相關文章
相關標籤/搜索