[Python] logN logN SortedList
python\nfrom sortedcontainers import SortedList\n\n\nclass ExamRoom:\n\n    def __init__(self, N: int):\n        self.starts = dict()\n        self.ends = dict(
```python\nfrom sortedcontainers import SortedList\n\n\nclass ExamRoom:\n\n    def __init__(self, N: int):\n        self.starts = dict()\n        self.ends = dict()\n        # Alternative Heap \n        self.fragments = SortedList()\n        self.n = N\n        \n        self.add_fragment((0, N-1))\n    \n    def distance(self, s, e):\n        if s == 0:\n            return e\n        if e == self.n-1:\n            return e-s\n        mid = (s+e) // 2\n        return min(mid-s, e-mid)\n\n    def add_fragment(self, fragment):\n        s, e = fragment\n        if s > e:\n            return\n        self.starts[s] = self.ends[e] = fragment\n        self.fragments.add((self.distance(s,e), -s, -e))\n        \n    def remove_fragment(self, fragment):\n        s, e = fragment\n        if s > e:\n            return\n        self.starts.pop(s)\n        self.ends.pop(e)\n        self.fragments.remove((self.distance(s,e), -s, -e))\n        \n    def divideFragment(self, fragment):\n        s, e = fragment\n        if s == 0:\n            return s, [(s+1, e)]\n        elif e == self.n-1:\n            return e, [(s, e-1)]\n        mid = (s+e) // 2\n        return mid, [(s, mid-1), (mid+1, e)]\n    \n    def mergeFragment(self, left, right):\n        if left == None:\n            return (right[0]-1, right[1])\n        if right == None:\n            return (left[0], left[1]+1)\n        return (left[0], right[1])\n    \n    def seat(self) -> int:\n        # print(self.fragments)\n        _, s, e = self.fragments[-1]\n        s, e = -s, -e\n        \n        self.remove_fragment((s, e))\n        seat, fragments = self.divideFragment((s, e))\n        for frag in fragments:\n            self.add_fragment(frag)\n\n        return seat\n\n    def leave(self, p: int) -> None:\n        # print(self.fragments)\n        left, right = self.ends.get(p-1, None), self.starts.get(p+1, None)\n        if left:\n            self.remove_fragment(left)\n        if right:\n            self.remove_fragment(right)\n        if left == right == None:\n            fragment = (p, p)\n        else:\n            fragment = self.mergeFragment(left, right)\n        self.add_fragment(fragment)\n\n\n# Your ExamRoom object will be instantiated and called as such:\n# obj = ExamRoom(N)\n# param_1 = obj.seat()\n# obj.leave(p)\n```
[]