結果
問題 |
No.3167 [Cherry 7th Tune C] Cut in Queue
|
ユーザー |
![]() |
提出日時 | 2025-06-01 16:45:08 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,335 ms / 2,500 ms |
コード長 | 3,904 bytes |
コンパイル時間 | 414 ms |
コンパイル使用メモリ | 82,176 KB |
実行使用メモリ | 281,428 KB |
最終ジャッジ日時 | 2025-06-01 16:45:52 |
合計ジャッジ時間 | 43,480 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 2 |
other | AC * 43 |
ソースコード
from collections import defaultdict def op(x, y): return x+y class SegTree: def __init__(self, init_val, op, ide_ele): n = len(init_val) self.n = n self.op = op self.ide_ele = ide_ele self.num = 1 << (n - 1).bit_length() self.tree = [ide_ele] * 2 * self.num for i in range(n): self.tree[self.num + i] = init_val[i] for i in range(self.num - 1, 0, -1): self.tree[i] = self.op(self.tree[2 * i], self.tree[2 * i + 1]) def update(self, k, x): k += self.num self.tree[k] = x while k > 1: self.tree[k >> 1] = self.op(self.tree[k], self.tree[k ^ 1]) k >>= 1 def query(self, l, r): res = self.ide_ele l += self.num r += self.num while l < r: if l & 1: res = self.op(res, self.tree[l]) l += 1 if r & 1: res = self.op(res, self.tree[r - 1]) l >>= 1 r >>= 1 return res def __getitem__(self, n): return self.tree[self.num+n] def List(self): return self.tree[self.num:self.num+self.n] def max_right(self, l, f, limit): if l == self.n: return self.n l += self.num sm = self.ide_ele while True: while l%2 == 0: l >>= 1 if not f(self.op(sm, self.tree[l]), limit): while l < self.num: l <<= 1 if f(self.op(sm, self.tree[l]), limit): sm = self.op(sm, self.tree[l]) l += 1 return l-self.num sm = self.op(sm, self.tree[l]) l += 1 if l & -l == l: break return self.n def min_left(self, r, f, limit): if r == 0: return 0 r += self.num sm = self.ide_ele while True: r -= 1 while r > 1 and r%2 == 1: r >>= 1 if not f(self.op(self.tree[r], sm), limit): while r < self.num: r = 2*r+1 if f(self.op(self.tree[r], sm), limit): sm = self.op(self.tree[r], sm) r -= 1 return r+1-self.num sm = self.op(self.tree[r], sm) if r & -r == r: break return 0 def bisect_R(n, limit): return n < limit N = int(input()) A = list(map(int, input().split())) Q = int(input()) query = [list(map(int, input().split())) for _ in range(Q)] pre = defaultdict(int) nex = defaultdict(int) for i in range(N): if 1 <= i: pre[A[i]] = A[i-1] else: pre[A[i]] = -1 if i+1 < N: nex[A[i]] = A[i+1] else: nex[A[i]] = -1 O = [-1]*Q start = A[0] end = A[-1] B = N+1 for i in range(Q): if query[i][0] == 1: a = query[i][1] if a == 0: nex[end] = B pre[B] = end nex[B] = -1 end = B if start == -1: start = B else: if a == start: start = B pre[B] = pre[a] nex[B] = a if pre[B] != -1: nex[pre[B]] = B pre[a] = B O[i] = B B += 1 elif query[i][0] == 2: O[i] = start start = nex[start] C = [] for n, v in pre.items(): if v == -1: C.append(n) break while nex[C[-1]] != -1: C.append(nex[C[-1]]) IDX = defaultdict(int) for i in range(len(C)): IDX[C[i]] = i S = [0]*len(C) for a in A: S[IDX[a]] += 1 seg = SegTree(S, op, 0) for i in range(Q): if O[i] != -1: seg.update(IDX[O[i]], seg[IDX[O[i]]]^1) else: k = query[i][1] print(C[seg.max_right(0, bisect_R, k)])