Skip to content

Commit 5266be3

Browse files
authored
Create block-placement-queries.py
1 parent e3a5551 commit 5266be3

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

Python/block-placement-queries.py

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
# Time: O(qlogq)
2+
# Space: O(q)
3+
4+
from sortedcontainers import SortedList
5+
6+
7+
# sorted list, bit, fenwick tree
8+
class Solution(object):
9+
def getResults(self, queries):
10+
"""
11+
:type queries: List[List[int]]
12+
:rtype: List[bool]
13+
"""
14+
class BIT(object): # 0-indexed.
15+
def __init__(self, n, default=0, fn=lambda x, y: x+y):
16+
self.__bit = [default]*(n+1) # Extra one for dummy node.
17+
self.__default = default
18+
self.__fn = fn
19+
20+
def update(self, i, val):
21+
i += 1 # Extra one for dummy node.
22+
while i < len(self.__bit):
23+
self.__bit[i] = self.__fn(self.__bit[i], val)
24+
i += (i & -i)
25+
26+
def query(self, i):
27+
i += 1 # Extra one for dummy node.
28+
ret = self.__default
29+
while i > 0:
30+
ret = self.__fn(ret, self.__bit[i])
31+
i -= (i & -i)
32+
return ret
33+
34+
sl = SortedList(q[1] for q in queries if q[0] == 1)
35+
val_to_idx = {x:i for i, x in enumerate(sl)}
36+
bit = BIT(len(val_to_idx), fn=max)
37+
for i in xrange(len(sl)):
38+
bit.update(val_to_idx[sl[i]], sl[i]-(sl[i-1] if i-1 >= 0 else 0))
39+
result = []
40+
for q in reversed(queries):
41+
i = sl.bisect_left(q[1])
42+
if q[0] == 1:
43+
if i+1 < len(sl):
44+
bit.update(val_to_idx[sl[i+1]], sl[i+1]-(sl[i-1] if i-1 >= 0 else 0))
45+
del sl[i]
46+
else:
47+
result.append(q[1]-(sl[i-1] if i-1 >= 0 else 0) >= q[2] or (i-1 >= 0 and bit.query(val_to_idx[sl[i-1]]) >= q[2]))
48+
result.reverse()
49+
return result
50+
51+
52+
# Time: O(qlogq)
53+
# Space: O(q)
54+
from sortedcontainers import SortedList
55+
56+
57+
# sorted list, segment tree
58+
class Solution2(object):
59+
def getResults(self, queries):
60+
"""
61+
:type queries: List[List[int]]
62+
:rtype: List[bool]
63+
"""
64+
# Template:
65+
# https://github.com/kamyu104/LeetCode-Solutions/blob/master/Python/booking-concert-tickets-in-groups.py
66+
class SegmentTree(object):
67+
def __init__(self, N,
68+
build_fn=lambda _: None,
69+
query_fn=lambda x, y: y if x is None else x if y is None else max(x, y),
70+
update_fn=lambda x: x):
71+
self.tree = [None]*(1<<((N-1).bit_length()+1))
72+
self.base = len(self.tree)>>1
73+
self.query_fn = query_fn
74+
self.update_fn = update_fn
75+
for i in xrange(self.base, self.base+N):
76+
self.tree[i] = build_fn(i-self.base)
77+
for i in reversed(xrange(1, self.base)):
78+
self.tree[i] = query_fn(self.tree[i<<1], self.tree[(i<<1)+1])
79+
80+
def update(self, i, h):
81+
x = self.base+i
82+
self.tree[x] = self.update_fn(h)
83+
while x > 1:
84+
x >>= 1
85+
self.tree[x] = self.query_fn(self.tree[x<<1], self.tree[(x<<1)+1])
86+
87+
def query(self, L, R):
88+
L += self.base
89+
R += self.base
90+
left = right = None
91+
while L <= R:
92+
if L & 1:
93+
left = self.query_fn(left, self.tree[L])
94+
L += 1
95+
if R & 1 == 0:
96+
right = self.query_fn(self.tree[R], right)
97+
R -= 1
98+
L >>= 1
99+
R >>= 1
100+
return self.query_fn(left, right)
101+
102+
def update(x):
103+
sl.add(x)
104+
i = sl.bisect_left(x)
105+
st.update(val_to_idx[x], x-(sl[i-1] if i-1 >= 0 else 0))
106+
if i+1 < len(sl):
107+
st.update(val_to_idx[sl[i+1]], sl[i+1]-x)
108+
109+
val_to_idx = {x:i for i, x in enumerate(sorted(q[1] for q in queries if q[0] == 1))}
110+
st = SegmentTree(len(val_to_idx))
111+
sl = SortedList()
112+
result = []
113+
for q in queries:
114+
if q[0] == 1:
115+
update(q[1])
116+
else:
117+
i = sl.bisect_left(q[1])
118+
result.append(q[1]-(sl[i-1] if i-1 >= 0 else 0) >= q[2] or (i-1 >= 0 and st.query(0, val_to_idx[sl[i-1]]) >= q[2]))
119+
return result

0 commit comments

Comments
 (0)