結果

問題 No.3753 Certainly a Cretan
コンテスト
ユーザー lif4635
提出日時 2026-10-02 22:53:33
言語 PyPy3
(7.3.23 + ACL)
コンパイル:
pypy3 -mpy_compile _filename_
実行:
pypy3 _filename_
結果
AC  
実行時間 471 ms / 2,500 ms
+ 341µs
コード長 4,842 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 74 ms
コンパイル使用メモリ 83,644 KB
実行使用メモリ 298,584 KB
最終ジャッジ日時 2026-10-02 22:53:45
合計ジャッジ時間 10,441 ms
ジャッジサーバーID
(参考情報)
judge2_1 / judge4_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 46
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

# haru: pypy
import sys
input = sys.stdin.readline
II = lambda : int(input())
MI = lambda : map(int, input().split())
LI = lambda : [int(a) for a in input().split()]
SI = lambda : input().rstrip()
LLI = lambda n : [[int(a) for a in input().split()] for _ in range(n)]
LSI = lambda n : [input().rstrip() for _ in range(n)]
MI_1 = lambda : map(lambda x:int(x)-1, input().split())
LI_1 = lambda : [int(a)-1 for a in input().split()]

mod = 998244353
inf = 1001001001001001001
ordalp = lambda s : ord(s)-65 if s.isupper() else ord(s)-97
ordallalp = lambda s : ord(s)-39 if s.isupper() else ord(s)-97
yes = lambda : print("Yes")
no = lambda : print("No")
yn = lambda flag : print("Yes" if flag else "No")

prinf = lambda ans : print(ans if ans < 1000001001001001001 else -1)
alplow = "abcdefghijklmnopqrstuvwxyz"
alpup = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
alpall = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
URDL = {'U':(-1,0), 'R':(0,1), 'D':(1,0), 'L':(0,-1)}
DIR_4 = [[-1,0],[0,1],[1,0],[0,-1]]
DIR_8 = [[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]]
DIR_BISHOP = [[-1,1],[1,1],[1,-1],[-1,-1]]
prime60 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59]
sys.set_int_max_str_digits(0)
# sys.setrecursionlimit(10**6)
# import pypyjit
# pypyjit.set_param('max_unroll_recursion=-1')

from collections import defaultdict,deque
from heapq import heappop,heappush
from bisect import bisect_left,bisect_right
DD = defaultdict
BSL = bisect_left
BSR = bisect_right

class Comb:
    __slots__ = ["fac", "finv", "mod"]
    def __init__(self, lim:int, mod:int = mod):
        """
        mod : prime
        """
        self.fac = [1]*(lim+1)
        self.finv = [1]*(lim+1)
        self.mod = mod
        for i in range(2,lim+1):
            self.fac[i] = self.fac[i-1]*i%self.mod
        self.finv[lim] = pow(self.fac[lim],-1,mod)
        for i in range(lim,2,-1):
            self.finv[i-1] = self.finv[i]*i%self.mod
    
    def C(self, a, b):
        if b < 0 or a < b: return 0
        if a < 0: return 0
        return self.fac[a]*self.finv[b]%self.mod*self.finv[a-b]%self.mod
    
    def __call__(self, a, b):
        if b < 0 or a < b: return 0
        if a < 0: return 0
        return self.fac[a]*self.finv[b]%self.mod*self.finv[a-b]%self.mod
    
    def P(self, a, b):
        if b < 0 or a < b: return 0
        if a < 0: return 0
        return self.fac[a]*self.finv[a-b]%self.mod
    
    def M(self, *k):
        n = sum(k)
        if n < 0: return 0
        res = self.fac[n]
        for ki in k:
            if ki < 0: return 0
            res = res * self.finv[ki] % self.mod
        return res
    
    def H(self, a, b): return self.C(a+b-1,b)
    def F(self, a): return self.fac[a]
    def Fi(self, a): return self.finv[a]

def run_length_encode(s):
    encoded = []
    n = len(s)
    i = 0
    while i < n:
        current_char = s[i]
        count = 0
        while i < n and s[i] == current_char:
            count += 1
            i += 1
        encoded.append((current_char, count))
    return encoded

"""
(自分含めて)

同数のとき
-> 自分の発言の逆

正直が多いとき
-> どっちでも Y

嘘つきが多いとき
-> どっちでも N

基本偶数長

で




"""

from atcoder.segtree import SegTree

n, q = map(int, input().split())
s = [x == "Y" for x in SI()]

comb = Comb(n + 10)

cat = [0] * (n + 1)
for i in range(n):
    if i & 1 == 0:
        cat[i] = (comb(i, i//2) - comb(i, i//2-1)) % mod


# le, l, r, p, s, v 
e = (0, 0, 0, 0, 0, 1)

def op(a, b):
    if a[0] == 0: return b
    if b[0] == 0: return a

    na, la, ra, pa, sa, va = a
    nb, lb, rb, pb, sb, vb = b

    eqa = (pa == na)
    eqb = (pb == nb)
    eq = (ra == lb)
    
    p = na + pb if eqa and eq else pa
    s = nb + sa if eqb and eq else sb
    v = va * vb % mod
    
    if eq:
        # 真ん中の merge
        if not eqa and not eqb:
            v = v * cat[sa + pb] % mod
    else:
        # merge できないとき
        if not eqa:
            v = v * cat[sa] % mod
        if not eqb:
            v = v * cat[pb] % mod
    return na + nb, la, rb, p, s, v


tmp = [(1, 0, 0, 1, 1, 1), (1, 1, 1, 1, 1, 1)]
seg = SegTree(op, e, [tmp[x] for x in s])


def calc(k):
    n, l, r, p, s, v = seg.all_prod()
    # print(n, l, r, p, s, v, k)
    
    # 先頭
    if p != n:
        v = v * cat[p] % mod
    
    # のこり
    k -= (n - s) // 2
    
    # print(n, l, r, p, s, v, k)
    
    if not 0 <= k <= s:
        return 0
    
    # すくないほう
    if r == 1:
        t = k
    else:
        t = s - k
        
    if not 0 <= t <= s // 2:
        return 0
    
    # print(s, t)
    t = comb(s, t) - comb(s, t-1)

    return v * t % mod

for _ in range(q):
    t, x = MI()
    if t == 1:
        x -= 1
        s[x] ^= 1
        seg.set(x, tmp[s[x]])
    else:
        print(calc(x))
0