結果
| 問題 |
No.3327 うるせぇ、ポリオミノぶつけんぞ
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-11-05 16:46:27 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 5,388 bytes |
| コンパイル時間 | 309 ms |
| コンパイル使用メモリ | 82,164 KB |
| 実行使用メモリ | 273,144 KB |
| 最終ジャッジ日時 | 2025-11-05 16:46:34 |
| 合計ジャッジ時間 | 6,773 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 7 TLE * 1 -- * 16 |
ソースコード
import bisect
INF = 10**18
class LazySegTree:
"""
1-indexedで使う範囲加算セグ木
- range_add(l, r, val): 区間[l, r]にvalを加算
- range_min(l, r): 区間[l, r]の(最小値, index)
- range_max(l, r): 区間[l, r]の(最大値, index)
- point_set(pos, val): 要素posをvalに変更
- point_get(pos): 要素posの現在値を返す
"""
def __init__(self, n):
self.N = n
self.size = 1
while self.size < n:
self.size <<= 1
# 各ノードに (値, インデックス)
self.minv = [(INF, -1) for _ in range(2 * self.size)]
self.maxv = [(-INF, -1) for _ in range(2 * self.size)]
self.lazy = [0] * (2 * self.size)
# 葉のindexを設定
for i in range(n):
pos = i + 1
self.minv[self.size + i] = (INF, pos)
self.maxv[self.size + i] = (-INF, pos)
for i in range(self.size - 1, 0, -1):
self._pull(i)
# 子ノードから親ノードを再計算
def _pull(self, idx):
self.minv[idx] = min(self.minv[idx * 2], self.minv[idx * 2 + 1], key=lambda x: x[0])
self.maxv[idx] = max(self.maxv[idx * 2], self.maxv[idx * 2 + 1], key=lambda x: x[0])
# ノードに遅延を適用
def _apply(self, idx, val):
vmin, pmin = self.minv[idx]
vmax, pmax = self.maxv[idx]
self.minv[idx] = (vmin + val, pmin)
self.maxv[idx] = (vmax + val, pmax)
if idx < self.size:
self.lazy[idx] += val
# 遅延を子に伝搬
def _push(self, idx):
if self.lazy[idx] != 0:
self._apply(idx * 2, self.lazy[idx])
self._apply(idx * 2 + 1, self.lazy[idx])
self.lazy[idx] = 0
# 区間加算 [l, r](1-indexed)
def range_add(self, l, r, val):
def _range_add(idx, nl, nr):
if r < nl or nr < l:
return
if l <= nl and nr <= r:
self._apply(idx, val)
return
self._push(idx)
mid = (nl + nr) // 2
_range_add(idx * 2, nl, mid)
_range_add(idx * 2 + 1, mid + 1, nr)
self._pull(idx)
_range_add(1, 1, self.size)
# 区間最小 (値, index)
def range_min(self, l, r):
res = (INF, -1)
def _range_min(idx, nl, nr):
nonlocal res
if r < nl or nr < l:
return
if l <= nl and nr <= r:
res = min(res, self.minv[idx], key=lambda x: x[0])
return
self._push(idx)
mid = (nl + nr) // 2
_range_min(idx * 2, nl, mid)
_range_min(idx * 2 + 1, mid + 1, nr)
_range_min(1, 1, self.size)
return res
# 区間最大 (値, index)
def range_max(self, l, r):
res = (-INF, -1)
def _range_max(idx, nl, nr):
nonlocal res
if r < nl or nr < l:
return
if l <= nl and nr <= r:
res = max(res, self.maxv[idx], key=lambda x: x[0])
return
self._push(idx)
mid = (nl + nr) // 2
_range_max(idx * 2, nl, mid)
_range_max(idx * 2 + 1, mid + 1, nr)
_range_max(1, 1, self.size)
return res
# 1点の値を設定
def point_set(self, pos, val):
def _set(idx, nl, nr):
if nl == nr:
self.minv[idx] = (val, pos)
self.maxv[idx] = (val, pos)
self.lazy[idx] = 0
return
self._push(idx)
mid = (nl + nr) // 2
if pos <= mid:
_set(idx * 2, nl, mid)
else:
_set(idx * 2 + 1, mid + 1, nr)
self._pull(idx)
_set(1, 1, self.size)
# 1点の値を取得
def point_get(self, pos):
def _get(idx, nl, nr):
if nl == nr:
return self.minv[idx][0]
self._push(idx)
mid = (nl + nr) // 2
if pos <= mid:
return _get(idx * 2, nl, mid)
else:
return _get(idx * 2 + 1, mid + 1, nr)
return _get(1, 1, self.size)
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)