-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathSumOfTopK.py
64 lines (52 loc) · 1.54 KB
/
SumOfTopK.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
from heapq import *
class deletable_heapq:
def __init__(self, initial = []):
if initial:
self.q = initial
heapify(self.q)
else: self.q = []
self.q_del = []
def propagate(self):
while self.q_del and self.q[0] == self.q_del[0]:
heappop(self.q)
heappop(self.q_del)
def heappop(self):
self.propagate()
return heappop(self.q)
def __len__(self):
return len(self.q) - len(self.q_del)
def top(self):
self.propagate()
return self.q[0]
def remove(self,x):
heappush(self.q_del,x)
def heappush(self,x):
heappush(self.q,x)
class SumOfTopK:
def __init__(self, K, initial = []):
#assert len(initial) <= K
self.K = K
self.val = sum(initial)
initial.sort()
self.q_topK = deletable_heapq(initial[:K])
self.q_other = deletable_heapq(initial[K:])
def get(self):
return self.val
def add(self,v):
self.q_topK.heappush(v)
self.val += v
if len(self.q_topK) == self.K+1:
x = self.q_topK.heappop()
self.val -= x
self.q_other.heappush(-x)
def remove(self,v):
t = self.q_topK.top()
if t <= v:
self.q_topK.remove(v)
self.val -= v
if len(self.q_other):
x = -self.q_other.heappop()
self.val += x
self.q_topK.heappush(x)
else:
self.q_other.remove(-v)