結果
| 問題 |
No.2901 Logical Sum of Substring
|
| コンテスト | |
| ユーザー |
lam6er
|
| 提出日時 | 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()
lam6er