結果

問題 No.3753 Certainly a Cretan
コンテスト
ユーザー marc2825
提出日時 2026-08-19 00:30:01
言語 PyPy3
(7.3.23 + ACL)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
RE  
実行時間 -
コード長 2,568 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 65 ms
コンパイル使用メモリ 83,436 KB
実行使用メモリ 75,348 KB
最終ジャッジ日時 2026-10-02 20:55:59
合計ジャッジ時間 5,159 ms
ジャッジサーバーID
(参考情報)
judge2_0 / judge1_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample RE * 2
other RE * 46
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

from sortedcontainers import SortedSet

MOD = 998244353

N, Q = map(int, input().split())
S = list(input())

fact = [1] * (N + 1)
invfact = [1] * (N + 1)
for i in range(1, N + 1):
    fact[i] = fact[i - 1] * i % MOD

invfact[N] = pow(fact[N], MOD - 2, MOD)

for i in range(N, 0, -1):
    invfact[i - 1] = invfact[i] * i % MOD


def C(n, k):
    if k < 0 or k > n:
        return 0
    return fact[n] * invfact[k] % MOD * invfact[n - k] % MOD


M = N // 2

cat = [1] * (M + 1)
invcat = [1] * (M + 1)
for r in range(M + 1):
    cat[r] = fact[2 * r] * invfact[r] % MOD * invfact[r + 1] % MOD
    invcat[r] = invfact[2 * r] * fact[r] % MOD * fact[r + 1] % MOD


T = SortedSet([0])
bad = 0
for i in range(1, N):
    if S[i - 1] == S[i]:
        continue

    if i % 2 == 1:
        bad += 1
    else:
        T.add(i)


P = 1
for j in range(1, len(T)):
    l = T[j - 1]
    r = T[j]

    P = P * cat[(r - l) // 2] % MOD


def insert(x):
    global P

    pos = T.bisect_left(x)

    l = T[pos - 1]

    if pos < len(T):
        r = T[pos]

        P = P * invcat[(r - l) // 2] % MOD
        P = P * cat[(x - l) // 2] % MOD
        P = P * cat[(r - x) // 2] % MOD
    else:
        P = P * cat[(x - l) // 2] % MOD

    T.add(x)


def erase(x):
    global P

    pos = T.bisect_left(x)

    l = T[pos - 1]

    if pos + 1 < len(T):
        r = T[pos + 1]

        P = P * invcat[(x - l) // 2] % MOD
        P = P * invcat[(r - x) // 2] % MOD
        P = P * cat[(r - l) // 2] % MOD
    else:
        P = P * invcat[(x - l) // 2] % MOD

    T.remove(x)


def check_boundary(x):
    global bad

    if x <= 0 or x >= N:
        return

    diff = S[x - 1] != S[x]

    if x % 2 == 1:
        if diff:
            bad -= 1
        else:
            bad += 1
    else:
        if diff:
            erase(x)
        else:
            insert(x)


for _ in range(Q):
    t, x = map(int, input().split())

    if t == 1:
        i = x

        check_boundary(i - 1)
        check_boundary(i)

        if S[i - 1] == 'Y':
            S[i - 1] = 'N'
        else:
            S[i - 1] = 'Y'

    else:
        K = x

        if bad > 0:
            print(0)
            continue

        B = T[-1]
        L = N - B
        q = K - B // 2

        if S[-1] == 'Y':
            if not (0 <= q <= L // 2):
                print(0)
                continue

            f = (C(L, q) - C(L, q - 1)) % MOD

        else:
            if not ((L + 1) // 2 <= q <= L):
                print(0)
                continue

            f = (C(L, q) - C(L, q + 1)) % MOD

        print(P * f % MOD)
0