結果
| 問題 |
No.3327 うるせぇ、ポリオミノぶつけんぞ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-05 16:52:30 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 6,047 bytes |
| コンパイル時間 | 388 ms |
| コンパイル使用メモリ | 82,380 KB |
| 実行使用メモリ | 201,068 KB |
| 最終ジャッジ日時 | 2025-11-05 16:53:17 |
| 合計ジャッジ時間 | 26,958 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 16 TLE * 8 |
ソースコード
import bisect
INF = 10**18
# 定数 INF は既存のまま使ってください
INF = 10**30 # 非常に大きな値(十分大きく)
class LazySegTree:
"""
超高速版(点更新 + 区間 min/max 特化、イテレーティブ実装)
- 1-indexed の要素位置を想定(main 側と互換)
- range_add は未実装(高速化のため省略)
- range_min(l,r) -> (min_value, index)
- range_max(l,r) -> (max_value, index)
- point_set(pos, val)
- point_get(pos)
"""
def __init__(self, n):
self.N = n
# サイズは葉の数(power of two)
size = 1
while size < n:
size <<= 1
self.size = size
m = 2 * size
# 値とインデックスを分離
self.minv = [INF] * m
self.minidx = [0] * m
self.maxv = [-INF] * m
self.maxidx = [0] * m
# 葉にインデックスをセット(leaf index = size + (pos-1))
# 値は INF / -INF のまま(外から point_set で設定する想定)
for i in range(n):
leaf = size + i
pos = i + 1 # 1-indexed position
self.minidx[leaf] = pos
self.maxidx[leaf] = pos
# 非効率だが確実に親インデックスを初期化(中身は後で point_set で入る)
for k in range(size - 1, 0, -1):
L = k * 2
R = L + 1
# minidx
if self.minv[L] <= self.minv[R]:
self.minv[k] = self.minv[L]
self.minidx[k] = self.minidx[L]
else:
self.minv[k] = self.minv[R]
self.minidx[k] = self.minidx[R]
# maxidx
if self.maxv[L] >= self.maxv[R]:
self.maxv[k] = self.maxv[L]
self.maxidx[k] = self.maxidx[L]
else:
self.maxv[k] = self.maxv[R]
self.maxidx[k] = self.maxidx[R]
# -------------------------
# 点更新(イテレーティブ)
# -------------------------
def point_set(self, pos, val):
# pos: 1-indexed
p = self.size + (pos - 1)
self.minv[p] = val
self.maxv[p] = val
# minidx/maxidx for leaves already set in __init__
p >>= 1
while p:
L = p * 2
R = L + 1
# min
if self.minv[L] <= self.minv[R]:
self.minv[p] = self.minv[L]
self.minidx[p] = self.minidx[L]
else:
self.minv[p] = self.minv[R]
self.minidx[p] = self.minidx[R]
# max
if self.maxv[L] >= self.maxv[R]:
self.maxv[p] = self.maxv[L]
self.maxidx[p] = self.maxidx[L]
else:
self.maxv[p] = self.maxv[R]
self.maxidx[p] = self.maxidx[R]
p >>= 1
# -------------------------
# 点取得(そのまま葉値返す)
# -------------------------
def point_get(self, pos):
p = self.size + (pos - 1)
return self.minv[p]
# -------------------------
# 区間最小クエリ(イテレーティブ)
# -------------------------
def range_min(self, l, r):
# l,r: 1-indexed, inclusive
l = l + self.size - 1
r = r + self.size - 1
best_val = INF
best_idx = -1
while l <= r:
if (l & 1) == 1:
v = self.minv[l]
if v < best_val:
best_val = v
best_idx = self.minidx[l]
l += 1
if (r & 1) == 0:
v = self.minv[r]
if v < best_val:
best_val = v
best_idx = self.minidx[r]
r -= 1
l >>= 1
r >>= 1
return (best_val, best_idx)
# -------------------------
# 区間最大クエリ(イテレーティブ)
# -------------------------
def range_max(self, l, r):
l = l + self.size - 1
r = r + self.size - 1
best_val = -INF
best_idx = -1
while l <= r:
if (l & 1) == 1:
v = self.maxv[l]
if v > best_val:
best_val = v
best_idx = self.maxidx[l]
l += 1
if (r & 1) == 0:
v = self.maxv[r]
if v > best_val:
best_val = v
best_idx = self.maxidx[r]
r -= 1
l >>= 1
r >>= 1
return (best_val, best_idx)
# -------------------------
# range_add は未実装(要求があれば追加)
# -------------------------
def range_add(self, l, r, val):
raise NotImplementedError("range_add is not implemented in this ultra-fast variant")
N, Q = (int(x) for x in input().split())
A=list(map(int, input().split()))
mem=[]
segm = LazySegTree(N)
segM = LazySegTree(N)
for num, i in enumerate(A, start = 1):
mem.append([i, num])
mem=sorted(mem, key=lambda x: x[0])
L=[]
for num, i in enumerate(mem, start = 1):
segm.point_set(num, i[1])
segM.point_set(num, i[1])
L.append([i[0], num])
ans=[]
for i in range(Q):
c, X = (int(x) for x in input().split())
idx = bisect.bisect_left(L, [X+1, -100])
if idx == len(L):
ans.append(-1)
continue
if c == 1:
num, sidx = L[idx]
res, seg_idx = segm.range_min(sidx, N)
if res == -1 or res == 1000000000:
ans.append(-1)
else:
ans.append(res)
segm.point_set(seg_idx, 1000000000)
segM.point_set(seg_idx, -1)
else:
num, sidx = L[idx]
res, seg_idx = segM.range_max(sidx, N)
if res == -1 or res == 1000000000:
ans.append(-1)
else:
ans.append(res)
segm.point_set(seg_idx, 1000000000)
segM.point_set(seg_idx, -1)
for i in ans:
print(i)