結果
問題 | No.2762 Counting and Deleting |
ユーザー |
|
提出日時 | 2024-05-09 13:41:31 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 609 ms / 4,000 ms |
コード長 | 3,496 bytes |
コンパイル時間 | 276 ms |
コンパイル使用メモリ | 82,468 KB |
実行使用メモリ | 123,592 KB |
最終ジャッジ日時 | 2024-12-16 03:32:06 |
合計ジャッジ時間 | 6,904 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 15 |
ソースコード
import sysdef debug(text):print("\033[36m" + str(text) + "\033[m", file = sys.stderr)MOD = 998244353class BIT:def __init__(self, n):if type(n) is list:self.tree = [0] + nn = len(n)for v in range(1, n):p = v + (-v & v)if p <= n:self.tree[p] += self.tree[v]else:self.tree = [0] * (n + 1)self.len = nself.depth = n.bit_length()def sum(self, l, r):return self.prefix_sum(r) - self.prefix_sum(l)def prefix_sum(self, r):s = 0while r > 0:s += self.tree[r]r -= -r & rreturn sdef add(self, i, x):i += 1while i <= self.len:self.tree[i] += xi += -i & i# min(x for x in range(0, self.len) if self.prefix_sum(x) >= x)def lower_bound(self, x):if x == 0:return 0s = 0p = 0for i in range(self.depth, -1, -1):k = p + (1 << i)if k <= self.len and s + self.tree[k] < x:s += self.tree[k]p += 1 << ireturn p + 1class Segtree:def op(self, x, y):a, b, c, d, e, f = xg, h, i, j, k, l = yreturn ((a * g + b * j) % MOD,(a * h + b * k) % MOD,(a * i + b * l + c) % MOD,(d * g + e * j) % MOD,(d * h + e * k) % MOD,(d * i + e * l + f) % MOD,)def e(self):return (1, 0, 0, 0, 1, 0)def __init__(self, a):if type(a) is int:a = [self.e()] * an = len(a)size = 1while size < n: size <<= 1self.tree = [self.e()] * (size * 2)for i, x in enumerate(a):self.tree[size + i] = xfor i in reversed(range(1, size)):self.tree[i] = self.op(self.tree[i << 1], self.tree[i << 1 | 1])self.size = sizedef __getitem__(self, p):return self.tree[self.size + p]def __setitem__(self, p, a):p += self.sizeself.tree[p] = awhile p > 1:p >>= 1self.tree[p] = self.op(self.tree[p << 1], self.tree[p << 1 | 1])def fold(self, l, r):x = self.e()y = self.e()l += self.sizer += self.sizewhile l < r:if l & 1 != 0:x = self.op(x, self.tree[l])l += 1l >>= 1if r & 1 != 0:r -= 1y = self.op(self.tree[r], y)r >>= 1return self.op(x, y)N, Q = map(int, input().split())S = input()queries = [list(map(int, input().split())) for _ in range(Q)]A0 = (1, 1, 0, 0, 1, 0)A1 = (1, 0, 0, 1, 1, 1)A_ = (1, 0, 0, 0, 1, 0)rest = BIT([1] * N)seg = Segtree([A0 if S[N - 1 - i] == "0" else A1 for i in range(N)])# debug(rest.tree)for t, l, r in queries:l -= 1if t == 1:# debug(f"remove [{l}, {r})")while l < r:lb = rest.lower_bound(rest.prefix_sum(l) + 1)# debug(f" lb={lb}")if lb == None or lb > r: breaki = lb - 1seg[N - 1 - i] = A_rest.add(i, -1)l = lb# debug(f" removed {i}")else:a, b, c, d, e, f = seg.fold(N - r, N - l)# debug((a, b, c, d, e, f))print((c + f) % MOD)