結果
問題 |
No.2080 Simple Nim Query
|
ユーザー |
![]() |
提出日時 | 2025-03-20 20:36:12 |
言語 | PyPy3 (7.3.15) |
結果 |
WA
|
実行時間 | - |
コード長 | 5,676 bytes |
コンパイル時間 | 235 ms |
コンパイル使用メモリ | 82,452 KB |
実行使用メモリ | 177,548 KB |
最終ジャッジ日時 | 2025-03-20 20:37:39 |
合計ジャッジ時間 | 6,829 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 3 WA * 5 |
ソースコード
import sys def main(): sys.setrecursionlimit(1 << 25) N, Q = map(int, sys.stdin.readline().split()) A = list(map(int, sys.stdin.readline().split())) # Segment tree for rightmost non-zero element class RightmostNonZeroNode: def __init__(self): self.pos = -1 self.value = 0 def merge(self, left, right): if right.pos != -1: self.pos = right.pos self.value = right.value else: self.pos = left.pos self.value = left.value if left.pos != -1 else 0 class RightmostNonZeroSegmentTree: def __init__(self, data): self.n = len(data) self.size = 1 while self.size < self.n: self.size <<= 1 self.tree = [RightmostNonZeroNode() for _ in range(2 * self.size)] for i in range(self.n): node = self.tree[self.size + i] if data[i] != 0: node.pos = i node.value = data[i] else: node.pos = -1 node.value = 0 for i in range(self.size - 1, 0, -1): self.tree[i].merge(self.tree[2*i], self.tree[2*i+1]) def update(self, pos, value): pos += self.size node = self.tree[pos] if value != 0: node.pos = pos - self.size node.value = value else: node.pos = -1 node.value = 0 pos >>= 1 while pos >= 1: self.tree[pos].merge(self.tree[2*pos], self.tree[2*pos+1]) pos >>= 1 def query_rightmost(self, l, r): l += self.size r += self.size res = RightmostNonZeroNode() while l <= r: if l % 2 == 1: current = self.tree[l] if current.pos != -1 and (res.pos == -1 or current.pos > res.pos): res.pos = current.pos res.value = current.value l += 1 if r % 2 == 0: current = self.tree[r] if current.pos != -1 and (res.pos == -1 or current.pos > res.pos): res.pos = current.pos res.value = current.value r -= 1 l >>= 1 r >>= 1 return res # Segment tree for checking if any non-zero in range class NonZeroCheckNode: def __init__(self): self.has_non_zero = False def merge(self, left, right): self.has_non_zero = left.has_non_zero or right.has_non_zero class NonZeroCheckSegmentTree: def __init__(self, data): self.n = len(data) self.size = 1 while self.size < self.n: self.size <<= 1 self.tree = [NonZeroCheckNode() for _ in range(2 * self.size)] for i in range(self.n): self.tree[self.size + i].has_non_zero = (data[i] != 0) for i in range(self.size - 1, 0, -1): self.tree[i].merge(self.tree[2*i], self.tree[2*i+1]) def update(self, pos, value): pos += self.size self.tree[pos].has_non_zero = (value != 0) pos >>= 1 while pos >= 1: prev = self.tree[pos].has_non_zero self.tree[pos].merge(self.tree[2*pos], self.tree[2*pos+1]) if prev == self.tree[pos].has_non_zero: break pos >>= 1 def query_has_non_zero(self, l, r): l += self.size r += self.size res = False while l <= r: if l % 2 == 1: res = res or self.tree[l].has_non_zero l += 1 if r % 2 == 0: res = res or self.tree[r].has_non_zero r -= 1 l >>= 1 r >>= 1 return res data = A # Build the two segment trees rnz_tree = RightmostNonZeroSegmentTree(data) check_tree = NonZeroCheckSegmentTree(data) for _ in range(Q): parts = sys.stdin.readline().split() if not parts: continue T = int(parts[0]) X = int(parts[1]) - 1 # convert to 0-based Y = int(parts[2]) if T == 1: # Update A[X] = Y rnz_tree.update(X, Y) check_tree.update(X, Y) else: # Query L = X R = Y - 1 # parts[2] was Y, the upper bound is 1-based, convert to 0-based # Find the rightmost non-zero in [L, R] res_node = rnz_tree.query_rightmost(L, R) if res_node.pos == -1: # All zeros print('S') continue value = res_node.value if value > 1: print('F') else: # Check if all to the left are zero left_L = L left_R = res_node.pos - 1 if left_L > left_R: # No elements to the left, output F print('F') else: has_non_zero = check_tree.query_has_non_zero(left_L, left_R) if has_non_zero: print('S') else: print('F') if __name__ == '__main__': main()