結果
問題 | No.2762 Counting and Deleting |
ユーザー | magurofly |
提出日時 | 2024-05-09 00:35:33 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 3,296 bytes |
コンパイル時間 | 440 ms |
コンパイル使用メモリ | 82,176 KB |
実行使用メモリ | 113,312 KB |
最終ジャッジ日時 | 2024-05-09 00:35:41 |
合計ジャッジ時間 | 6,722 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 39 ms
53,376 KB |
testcase_01 | AC | 39 ms
52,992 KB |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | AC | 40 ms
53,248 KB |
testcase_06 | AC | 39 ms
52,736 KB |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | AC | 463 ms
98,292 KB |
testcase_16 | AC | 423 ms
98,124 KB |
ソースコード
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 if self.tree[self.len] < x: return None 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)]) for t, l, r in queries: l -= 1 if t == 1: while l < r: lb = rest.lower_bound(rest.prefix_sum(l) + 1) if lb == None or lb > r: break i = lb - 1 seg[N - 1 - i] = A_ rest.add(i, -1) l = lb else: a, b, c, d, e, f = seg.fold(N - r, N - l) print((c + f) % MOD)