結果
| 問題 | No.3753 Certainly a Cretan |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2026-08-19 00:36:03 |
| 言語 | PyPy3 (7.3.23 + ACL) |
| 結果 |
AC
不安定
|
| 実行時間 | 429 ms / 2,500 ms |
| + 921µs | |
| コード長 | 3,280 bytes |
| 記録 | |
| コンパイル時間 | 69 ms |
| コンパイル使用メモリ | 82,548 KB |
| 実行使用メモリ | 160,016 KB |
| 最終ジャッジ日時 | 2026-10-02 20:56:15 |
| 合計ジャッジ時間 | 8,139 ms |
|
ジャッジサーバーID (参考情報) |
judge1_0 / judge2_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 46 |
ソースコード
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
def cat(r):
return fact[2 * r] * invfact[r] % MOD * invfact[r + 1] % MOD
def invcat(r):
return invfact[2 * r] * fact[r] % MOD * fact[r + 1] % MOD
# bit[x + 1] に
# 「位置 x が偶数位置の切り替わり、または x = 0 なら 1」
# を持たせる
bit = [0] * (N + 1)
bit[1] = 1
cnt = 1
bad = 0
P = 1
last = 0
for i in range(1, N):
if S[i - 1] == S[i]:
continue
if i % 2 == 1:
bad += 1
else:
bit[i + 1] = 1
cnt += 1
P = P * cat((i - last) // 2) % MOD
last = i
for i in range(1, N + 1):
j = i + (i & -i)
if j <= N:
bit[j] += bit[i]
def add(pos, x):
i = pos + 1
while i <= N:
bit[i] += x
i += i & -i
def prefix_sum(pos):
if pos < 0:
return 0
i = pos + 1
res = 0
while i > 0:
res += bit[i]
i -= i & -i
return res
def kth(k):
idx = 0
d = 1 << (N.bit_length() - 1)
while d:
nxt = idx + d
if nxt <= N and bit[nxt] < k:
idx = nxt
k -= bit[nxt]
d >>= 1
return idx
def prev_boundary(x):
k = prefix_sum(x - 1)
return kth(k)
def next_boundary(x):
k = prefix_sum(x)
if k == cnt:
return -1
return kth(k + 1)
def insert(x):
global P, cnt
l = prev_boundary(x)
r = next_boundary(x)
if r != -1:
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
add(x, 1)
cnt += 1
def erase(x):
global P, cnt
l = prev_boundary(x)
r = next_boundary(x)
if r != -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
add(x, -1)
cnt -= 1
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)
S[i - 1] = 'N' if S[i - 1] == 'Y' else 'Y'
else:
K = x
if bad > 0:
print(0)
continue
B = kth(cnt)
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)