C# solution (prefixSum + binary search)
```\npublic class Solution {\n\n    public Random random;\n    public int[][] rects;\n    \n    public int[] areasPrefixSum;\n    public int areaSum;\n    \n   
```\npublic class Solution {\n\n    public Random random;\n    public int[][] rects;\n    \n    public int[] areasPrefixSum;\n    public int areaSum;\n    \n    public Solution(int[][] rects) {\n        \n        random = new Random();\n        this.rects = rects;      \n        areasPrefixSum = new int[rects.Length];\n        \n        for(int i = 0; i < rects.Length; i++)\n        {           \n            // area: total points can be picked from current rectangle\n            int area= (rects[i][2] - rects[i][0] + 1) * (rects[i][3] - rects[i][1] + 1);\n            \n            // areasPrefixSum[i]: total number of points can be picked from 0-th retangle to i-th retangle\n            areasPrefixSum[i] = i == 0 ? area: areasPrefixSum[i - 1] + area;\n        }        \n        \n        areaSum = areasPrefixSum[rects.Length - 1];        \n    }\n    \n    public int[] Pick() {\n        \n        int target = random.Next(0, areaSum) + 1;         \n        int rectIndex = BinarySearch(areasPrefixSum, target);\n\n        int x = random.Next(rects[rectIndex][0], rects[rectIndex][2] + 1);\n        int y = random.Next(rects[rectIndex][1], rects[rectIndex][3] + 1);\n        \n        return new int[]{x, y};\n    }\n    \n    public int BinarySearch(int[] arr, int target)\n    {\n        int left = 0, right = arr.Length - 1;\n        \n        while(left <= right)\n        {\n            int mid = (right - left) + left / 2;\n            if(arr[mid] == target)\n                return mid;\n            if(arr[mid] > target)\n                right = mid - 1;\n            else\n                left = mid + 1;\n        }\n        \n        return left;\n    }\n}
[]