<p>You are given a 2D integer array <code>items</code> where <code>items[i] = [price<sub>i</sub>, beauty<sub>i</sub>]</code> denotes the <strong>price</strong> and <strong>beauty</strong> of an item respectively.</p>

<p>You are also given a <strong>0-indexed</strong> integer array <code>queries</code>. For each <code>queries[j]</code>, you want to determine the <strong>maximum beauty</strong> of an item whose <strong>price</strong> is <strong>less than or equal</strong> to <code>queries[j]</code>. If no such item exists, then the answer to this query is <code>0</code>.</p>

<p>Return <em>an array </em><code>answer</code><em> of the same length as </em><code>queries</code><em> where </em><code>answer[j]</code><em> is the answer to the </em><code>j<sup>th</sup></code><em> query</em>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> items = [[1,2],[3,2],[2,4],[5,6],[3,5]], queries = [1,2,3,4,5,6]
<strong>Output:</strong> [2,4,5,5,6,6]
<strong>Explanation:</strong>
- For queries[0]=1, [1,2] is the only item which has price &lt;= 1. Hence, the answer for this query is 2.
- For queries[1]=2, the items which can be considered are [1,2] and [2,4]. 
  The maximum beauty among them is 4.
- For queries[2]=3 and queries[3]=4, the items which can be considered are [1,2], [3,2], [2,4], and [3,5].
  The maximum beauty among them is 5.
- For queries[4]=5 and queries[5]=6, all items can be considered.
  Hence, the answer for them is the maximum beauty of all items, i.e., 6.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> items = [[1,2],[1,2],[1,3],[1,4]], queries = [1]
<strong>Output:</strong> [4]
<strong>Explanation:</strong> 
The price of every item is equal to 1, so we choose the item with the maximum beauty 4. 
Note that multiple items can have the same price and/or beauty.  
</pre>

<p><strong class="example">Example 3:</strong></p>

<pre>
<strong>Input:</strong> items = [[10,1000]], queries = [5]
<strong>Output:</strong> [0]
<strong>Explanation:</strong>
No item has a price less than or equal to 5, so no item can be chosen.
Hence, the answer to the query is 0.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= items.length, queries.length &lt;= 10<sup>5</sup></code></li>
	<li><code>items[i].length == 2</code></li>
	<li><code>1 &lt;= price<sub>i</sub>, beauty<sub>i</sub>, queries[j] &lt;= 10<sup>9</sup></code></li>
</ul>

from typing import List


class Shop:
	def __init__(self):
		self.min = None
		self.max = None
		self.items = []

	def add(self, items: List[List[int]]):
		sorted_items = sorted(items, key=lambda x: (x[0], -x[1]))
		max_beauty = sorted_items[0][1]
		self.items.append(sorted_items[0])
		self.min = sorted_items[0][0]
		self.max = sorted_items[-1][0]
		for i in range(1, len(sorted_items)):
			price, beauty = sorted_items[i]
			if beauty > max_beauty:
				self.items.append([price, beauty])
				max_beauty = beauty

	def get(self, price: int):
		if price < self.min:
			return 0
		if price >= self.max:
			return self.items[-1][1]

		l, r = 0, len(self.items) - 1
		m = (l + r) // 2
		while l <= r:
			curr_price = self.items[m][0]
			if curr_price == price:
				return self.items[m][1]
			elif curr_price > price:
				r = m - 1
			else:
				l = m + 1
			m = (l + r) // 2
		return self.items[m][1]


class Solution:
	def maximumBeauty(self, items: List[List[int]], queries: List[int]) -> List[int]:
		shop = Shop()
		shop.add(items)
		return [shop.get(query) for query in queries]

683