結果
問題 |
No.2901 Logical Sum of Substring
|
ユーザー |
![]() |
提出日時 | 2025-03-26 15:57:52 |
言語 | PyPy3 (7.3.15) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,952 bytes |
コンパイル時間 | 421 ms |
コンパイル使用メモリ | 82,412 KB |
実行使用メモリ | 129,060 KB |
最終ジャッジ日時 | 2025-03-26 15:58:54 |
合計ジャッジ時間 | 8,742 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 9 TLE * 1 -- * 20 |
ソースコード
import sys def main(): input = sys.stdin.read().split() ptr = 0 N, K = int(input[ptr]), int(input[ptr+1]) ptr +=2 A = list(map(int, input[ptr:ptr+N])) ptr +=N Q = int(input[ptr]) ptr +=1 queries = [] for _ in range(Q): query = input[ptr] if query == '1': i = int(input[ptr+1]) v = int(input[ptr+2]) queries.append( (1, i-1, v) ) ptr +=3 else: l = int(input[ptr+1]) r = int(input[ptr+2]) queries.append( (2, l-1, r-1) ) ptr +=3 target = (1 << K) -1 # Precompute bits for each number bits_for_num = [] for num in A: bits = [] for b in range(K): if (num >> b) & 1: bits.append(b) bits_for_num.append(bits) # Segment tree to check if any element in [l, r] is target class SegmentTree: def __init__(self, data): self.n = len(data) self.tree = [False] * (4 * self.n) self.build(0, 0, self.n-1, data) def build(self, node, l, r, data): if l == r: self.tree[node] = (data[l] == target) return mid = (l + r) // 2 self.build(2*node+1, l, mid, data) self.build(2*node+2, mid+1, r, data) self.tree[node] = self.tree[2*node+1] or self.tree[2*node+2] def update(self, node, l, r, idx, value): if l == r: self.tree[node] = (value == target) return mid = (l + r) // 2 if idx <= mid: self.update(2*node+1, l, mid, idx, value) else: self.update(2*node+2, mid+1, r, idx, value) self.tree[node] = self.tree[2*node+1] or self.tree[2*node+2] def query(self, node, l, r, ql, qr): if r < ql or l > qr: return False if ql <= l and r <= qr: return self.tree[node] mid = (l + r) // 2 left = self.query(2*node+1, l, mid, ql, qr) right = self.query(2*node+2, mid+1, r, ql, qr) return left or right st = SegmentTree(A) for query in queries: if query[0] == 1: i, v = query[1], query[2] A[i] = v # Update bits_for_num new_bits = [] for b in range(K): if (v >> b) & 1: new_bits.append(b) bits_for_num[i] = new_bits st.update(0, 0, N-1, i, v) else: l, r = query[1], query[2] # Check if any element is target has_target = st.query(0, 0, N-1, l, r) if has_target: print(1) continue # Sliding window approach to find minimal window with all K bits last_occurrence = [0] * K count = 0 left = l min_length = float('inf') for right in range(l, r + 1): # Update count and last_occurrence for bits in A[right] for b in bits_for_num[right]: if last_occurrence[b] == 0: count += 1 last_occurrence[b] += 1 # Try to shrink the window from the left while count == K: current_length = right - left + 1 if current_length < min_length: min_length = current_length # Move left pointer for b in bits_for_num[left]: last_occurrence[b] -= 1 if last_occurrence[b] == 0: count -= 1 left += 1 if min_length != float('inf'): print(min_length) else: print(-1) if __name__ == "__main__": main()