結果
問題 | No.2809 Sort Query |
ユーザー |
![]() |
提出日時 | 2024-07-13 00:38:15 |
言語 | PyPy3 (7.3.15) |
結果 |
AC
|
実行時間 | 1,445 ms / 2,000 ms |
コード長 | 3,464 bytes |
コンパイル時間 | 626 ms |
コンパイル使用メモリ | 82,276 KB |
実行使用メモリ | 274,136 KB |
最終ジャッジ日時 | 2024-07-13 00:39:36 |
合計ジャッジ時間 | 78,993 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge1 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 71 |
ソースコード
#yukicoder 2809 Sort Query#Binary Indexed Treeclass BinaryIndexedTree:def __init__(self, N): self._N, self.bit = N, [0] * (N + 1)def build(self, A): #O(N)で構築C = [0] * (self._N + 1)for i in range(self._N): C[i + 1] = C[i] + A[i]for e in range( self._N.bit_length() ):d = 1 << efor L in range(0, self._N + 1 - d, d << 1): self.bit[L + d] = C[L + d] - C[L]def add(self, i, x): #A[i] += xi += 1while i <= self._N: self.bit[i] += x; i += i & - idef sum(self, i): #sum(A[0, 1, ・・・ , i])ans, i = 0, i + 1while i > 0: ans += self.bit[i]; i -= i & - ireturn ansdef fold(self, Lt, Rt): #半開区間A[Lt: Rt)の和ans = 0while Lt != Rt:if Lt > Rt: ans -= self.bit[Lt]; Lt -= Lt & - Ltelse: ans += self.bit[Rt]; Rt -= Rt & - Rtreturn ans#down: Falseなら単調増加、Trueなら単調減少を仮定する。#sum(i)の作用値がX以上/以下となる、最小のiを返すdef bisect(self, X, down = False):b = (self._N + 1).bit_length() - 1; i, d = 1 << b, 1 << (b - 1); cnt = 0for b in range(b, -1, -1):if i > self._N: i -= d; d >>= 1elif not down and cnt + self.bit[i] >= X: i -= d; d >>= 1elif down and cnt + self.bit[i] <= X: i -= d; d >>= 1elif b == 0: return ielse: cnt += self.bit[i]; i += d; d >>= 1return i - 1#入力受取 座標圧縮N, Q = map(int, input().split())A = list(map(int, input().split()))D = A[:]query = [None] * Qfor q in range(Q):t, *k = map(int, input().split())if t == 1:k, x = kquery[q] = (t, k - 1, x)D.append(x)if t == 2:query[q] = (t, 0, 0)if t == 3:k = k[0]query[q] = (t, k - 1, 0)D.sort()nD = []for d in D:if len(nD) == 0 or nD[-1] != d:nD.append(d)D = nDE = {j: i for i, j in enumerate(D)}n = len(E)A = [E[i] for i in A]ans = []R = [-1] * Qfor q, (t, k, x) in enumerate(query):if t == 1:query[q] = (t, k, E[x])if t == 3:ans.append(-1)R[q] = len(ans) - 1#ソートの影響を受けないものと、ソートの影響を受ける場合は何回目のソートか調べるB = A[:]S = set(range(N))X = []for q, (t, k, x) in enumerate(query):if t == 1:B[k] = xS.add(k)if t == 2:S.clear()X.append([])if t == 3:if k in S:ans[R[q]] = B[k]else:X[-1].append((R[q], k))#X[ソート回数]: (ansのindex, ソート順でk個目)BIT = BinaryIndexedTree(n)B = [0] * nfor Ai in A:B[Ai] += 1BIT.build(B)cnt = -1diff = dict()for q, (t, k, x) in enumerate(query):if t == 1:if cnt == -1:BIT.add(A[k], -1)A[k] = xBIT.add(A[k], +1)else:diff[k] = x #変更フォルダに保存if t == 2:#1. 変更を保存if cnt >= 0:diff2 = dict()for k in diff:diff2[k] = BIT.bisect(k + 1)for k in diff:BIT.add(diff[k], +1)BIT.add(diff2[k], -1)cnt += 1diff = dict()#2. クエリに回答for q, k in X[cnt]:ans[q] = BIT.bisect(k + 1)for i in ans: print(D[i])