'''
就是不想写平衡树代码,代码太冗杂了,利用离散化加树状数组模拟BST行为
'''
import sys
class FenwickTree:
def __init__(self, data):
if len(data) == 0:
raise ValueError('data length is zero!')
self.n = len(data)
prefix_sum = [0] * (self.n + 1)
self.sum_seg = [0] * (self.n + 1) # 分段存储的区间和 sum_seg[x]表示的是x位置结尾,长度为x&(-x)的区间中的数值的和
# 实际存储时候错一位存储,外部数据的下标从0开始,但是树状数组的下标是从1开始的
i = 1
for val in data:
prefix_sum[i] = prefix_sum[i-1] + val
self.sum_seg[i] = prefix_sum[i] - prefix_sum[i & (i-1)]
i += 1
# 获取x位置的原始数值
def getOrigValue(self, x):
x += 1
if x < 1 or x > self.n:
raise IndexError(f'error idx = {x}')
ans = self.sum_seg[x]
lca = x & (x-1) # 最近公共祖先
x -= 1
while x != lca:
ans -= self.sum_seg[x]
x &= (x-1)
return ans
# 获取区间[0, end]的数值和
def __getSumWithEnd(self, end): # 这里end是内部坐标,不是外部坐标
ans = 0
while end:
ans += self.sum_seg[end]
end &= (end - 1)
return ans
# 获取区间的数据和
def getSum(self, start, end):
start, end = start+1, end+1
if not (end >= start and start >= 1 and end <= self.n):
raise IndexError(f'bad range {(start-1, end-1)}')
if start == 1:
return self.__getSumWithEnd(end)
return self.__getSumWithEnd(end) - self.__getSumWithEnd(start-1)
# 更新x位置数值
def updateValue(self, x, val):
orig_val = self.getOrigValue(x)
x += 1
delta = val - orig_val
while x <= self.n:
self.sum_seg[x] += delta
x += x & (-x)
# x位置增加数值delta
def addValue(self, x, delta):
x += 1
while x <= self.n:
self.sum_seg[x] += delta
x += x & (-x)
m = int(input())
cmds = []
all_vals = set()
for _ in range(m):
s = sys.stdin.readline()
cmd, val = map(int, s.split())
cmds.append((cmd, val))
all_vals.add(val)
vals = list(all_vals)
vals.sort()
val2idx = {val: idx for idx, val in enumerate(vals)}
val_num = len(vals)
val_cnts = [0] * val_num;
tree = FenwickTree([0]*val_num)
for cmd, val in cmds:
if cmd == 1:
tree.addValue(val2idx[val], 1)
elif cmd == 2:
tree.addValue(val2idx[val], -1)
elif cmd == 3:
print(tree.getSum(0, val2idx[val]-1) + 1)
elif cmd == 4:
l, r = 0, val_num-1
ans = -1
while l <= r:
mid = l + (r-l) // 2
if tree.getSum(0, mid) >= val:
ans = mid
r = mid-1
else:
l = mid+1
print(vals[ans])
elif cmd == 5:
l, r = 0, val2idx[val]-1
target_sum = tree.getSum(0, r)
ans = -1
while l <= r:
mid = l + (r-l) // 2
if tree.getSum(0, mid) == target_sum:
ans = mid
r = mid - 1
else:
l = mid + 1
print(vals[ans])
elif cmd == 6:
l, r = val2idx[val]+1, val_num-1
target_sum = tree.getSum(0, val2idx[val])
ans = -1
while l <= r:
mid = l + (r-l) // 2
if tree.getSum(0, mid) > target_sum:
ans = mid
r = mid - 1
else:
l = mid + 1
print(vals[ans])
这代码长度,还不如老老实实写平衡树呢