Explained Javascript Solution, Using binary search
\n/**\n /**\n * @param {number[][]} rects\n */\nvar Solution = function(rects) {\n    this.rects = rects;\n    this.map = {};\n    this.sum = 0;\n    // we put 
```\n/**\n /**\n * @param {number[][]} rects\n */\nvar Solution = function(rects) {\n    this.rects = rects;\n    this.map = {};\n    this.sum = 0;\n    // we put in the map the number of points that belong to each rect\n    for(let i in rects) {\n        const rect = rects[i];\n        // the number of points can be picked in this rectangle\n        this.sum += (rect[2] - rect[0] + 1) * (rect[3] - rect[1] + 1);\n        this.map[this.sum] = i;\n    }\n    this.keys = Object.keys(this.map);\n};\n\n/**\n * @return {number[]}\n */\nSolution.prototype.pick = function() {\n    // random point pick between [1, this.sum]\n    const randomPointPick = Math.floor(Math.random() * this.sum) + 1;\n    \n    // we look for the randomPointPick in the keys of the map\n    let pointInMap;\n    // the keys exists in map\n    if(this.map[randomPointPick]) pointInMap = randomPointPick;\n    // the key is the first in the map (we do this check before doing binary search because its out of boundery)\n    else if(randomPointPick < this.keys[0]) pointInMap = this.keys[0];\n    let high = this.keys.length;\n    let low = 1;\n    // binary search to find the closest key that bigger than randomPointPick\n    while(low <= high && !pointInMap) {\n        const mid = Math.floor((low + (high-low)/2));\n        if(randomPointPick > this.keys[mid-1] && randomPointPick < this.keys[mid]) {\n            pointInMap = this.keys[mid];\n            break;\n        } else if (randomPointPick > this.keys[mid]){\n            low = mid+1;\n        } else {\n            high = mid-1;\n        }\n    }\n    \n    // we have the point, now we can get which rect belong to that point\n    const pointInRects = this.map[pointInMap];\n    const chosen = this.rects[pointInRects];\n    const rightX = chosen[2];\n    const leftX = chosen[0];\n    const topY = chosen[3];\n    const bottomY = chosen[1];\n    const pickX = Math.floor(Math.random() * (rightX-leftX+1)) + leftX;\n    const pickY = Math.floor(Math.random() * (topY-bottomY+1)) + bottomY;\n    return [pickX, pickY]\n};\n\n/** \n * Your Solution object will be instantiated and called as such:\n * var obj = new Solution(rects)\n * var param_1 = obj.pick()\n */\n```
['Binary Tree', 'JavaScript']