結果
問題 | No.2762 Counting and Deleting |
ユーザー | magurofly |
提出日時 | 2024-05-09 13:41:31 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 655 ms / 4,000 ms |
コード長 | 3,496 bytes |
コンパイル時間 | 169 ms |
コンパイル使用メモリ | 82,396 KB |
実行使用メモリ | 124,312 KB |
最終ジャッジ日時 | 2024-05-09 13:41:39 |
合計ジャッジ時間 | 6,631 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge1 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 41 ms
52,736 KB |
testcase_01 | AC | 40 ms
53,248 KB |
testcase_02 | AC | 39 ms
53,376 KB |
testcase_03 | AC | 39 ms
53,376 KB |
testcase_04 | AC | 41 ms
53,376 KB |
testcase_05 | AC | 37 ms
52,864 KB |
testcase_06 | AC | 38 ms
52,864 KB |
testcase_07 | AC | 472 ms
109,612 KB |
testcase_08 | AC | 527 ms
109,280 KB |
testcase_09 | AC | 511 ms
110,556 KB |
testcase_10 | AC | 655 ms
112,872 KB |
testcase_11 | AC | 529 ms
124,312 KB |
testcase_12 | AC | 566 ms
123,596 KB |
testcase_13 | AC | 526 ms
122,020 KB |
testcase_14 | AC | 538 ms
122,564 KB |
testcase_15 | AC | 463 ms
98,548 KB |
testcase_16 | AC | 416 ms
98,380 KB |
ソースコード
import sys def debug(text): print("\033[36m" + str(text) + "\033[m", file = sys.stderr) MOD = 998244353 class BIT: def __init__(self, n): if type(n) is list: self.tree = [0] + n n = 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 = n self.depth = n.bit_length() def sum(self, l, r): return self.prefix_sum(r) - self.prefix_sum(l) def prefix_sum(self, r): s = 0 while r > 0: s += self.tree[r] r -= -r & r return s def add(self, i, x): i += 1 while i <= self.len: self.tree[i] += x i += -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 0 s = 0 p = 0 for 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 << i return p + 1 class Segtree: def op(self, x, y): a, b, c, d, e, f = x g, h, i, j, k, l = y return ( (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()] * a n = len(a) size = 1 while size < n: size <<= 1 self.tree = [self.e()] * (size * 2) for i, x in enumerate(a): self.tree[size + i] = x for i in reversed(range(1, size)): self.tree[i] = self.op(self.tree[i << 1], self.tree[i << 1 | 1]) self.size = size def __getitem__(self, p): return self.tree[self.size + p] def __setitem__(self, p, a): p += self.size self.tree[p] = a while p > 1: p >>= 1 self.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.size r += self.size while l < r: if l & 1 != 0: x = self.op(x, self.tree[l]) l += 1 l >>= 1 if r & 1 != 0: r -= 1 y = self.op(self.tree[r], y) r >>= 1 return 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 -= 1 if 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: break i = lb - 1 seg[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)