結果
| 問題 |
No.833 かっこいい電車
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-02-27 12:31:22 |
| 言語 | PyPy3 (7.3.15) |
| 結果 |
AC
|
| 実行時間 | 509 ms / 2,000 ms |
| コード長 | 2,739 bytes |
| コンパイル時間 | 348 ms |
| コンパイル使用メモリ | 82,048 KB |
| 実行使用メモリ | 99,540 KB |
| 最終ジャッジ日時 | 2024-10-02 17:25:04 |
| 合計ジャッジ時間 | 10,813 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 |
| other | AC * 30 |
ソースコード
class Bit:
"""1-indexed"""
def __init__(self, n):
self.size = n
self.tree = [0] * (n + 1)
def initialize(self, A):
for i, a in enumerate(A, 1):
self.tree[i] = a
j = (i & -i) >> 1
while j:
self.tree[i] += self.tree[i - j]
j >>= 1
def _sum(self, i):
s = 0
while i > 0:
s += self.tree[i]
i -= i & -i
return s
def sum(self, i, j):
"""閉区間[i, j]"""
return self._sum(j) - self._sum(i - 1)
def add(self, i, x):
while i <= self.size:
self.tree[i] += x
i += i & -i
class SegmentTree:
"""
https://tjkendev.github.io/procon-library/python/range_query/ruq_segment_tree.html から拝借しています。
"""
# N: 処理する区間の長さ
def __init__(self, N):
self.N = N
self.N0 = 2 ** (self.N - 1).bit_length()
self.data = [None] * (2 * self.N0)
self.INF = (-1, 2 ** 31 - 1)
# 区間[l, r)の値をvに書き換える
# vは(t, value)というタプルにする (新しい値ほどtは大きくなる)
def update(self, l, r, v):
L = l + self.N0
R = r + self.N0
while L < R:
if R & 1:
R -= 1
self.data[R - 1] = v
if L & 1:
self.data[L - 1] = v
L += 1
L >>= 1
R >>= 1
# a_iの現在の値を取得
def _query(self, k):
k += self.N0 - 1
s = self.INF
while k >= 0:
if self.data[k]:
s = max(s, self.data[k])
k = (k - 1) // 2
return s
# これを呼び出す
def query(self, k):
return self._query(k)[1]
N, Q = map(int, input().split())
A = map(int, input().split())
bit = Bit(N)
bit.initialize(A)
seg_left = SegmentTree(N)
seg_right = SegmentTree(N)
t = 0
for i in range(1, N + 1):
seg_left.update(i, i + 1, (t, i))
seg_right.update(i, i + 1, (t, i))
t += 1
for _ in range(Q):
q, x = map(int, input().split())
if q == 1:
new_left = seg_left.query(x)
new_right = seg_right.query(x + 1)
seg_left.update(x + 1, new_right + 1, (t, new_left))
seg_right.update(new_left, x + 1, (t, new_right))
t += 1
elif q == 2:
left = seg_left.query(x)
right = seg_right.query(x + 1)
seg_left.update(x + 1, right + 1, (t, x + 1))
seg_right.update(left, x + 1, (t, x))
t += 1
elif q == 3:
bit.add(x, 1)
else: # q==4
left = seg_left.query(x)
right = seg_right.query(x)
print(bit.sum(left, right))