../ Competitive Programming
-rw-r--r--aguang1.7 KiB2 min read

Leet Code Daily 2024-05-10 - K-th Smallest Prime Fraction

Solution

Monotonicity Optimization

First, let's define:

F(x,y)=∣{AiAj ∣ 0≤i<j<n∧AiAj≤AxAy}∣F(x, y) = \lvert \{ \frac{A_{i}}{A_j} \text{ } \lvert \text{ } 0 \leq i \lt j \lt n \land \frac{A_{i}}{A_j} \leq \frac{A_x}{A_y} \} \rvert

We know that for any AxAy\frac{A_x}{A_y}, we can compute F(x,y)F(x, y) in O(n)O(n) time.

Then we can enumerate x, and for each x, binary search:

arg max⁡yF(x,y)≥k\argmax_{y}{F(x, y) \geq k}

Time Complexity

O(n2×log⁡2n)O(n^2 \times \log_2{n})

Note

There might be some more efficient solution.

Code

c++
class Solution {
public:
    bool fracCmp(int x1, int y1, int x2, int y2) { return x1 * y2 <= x2 * y1; }

    int fracCnt(const vector<int>& arr, int x, int y) {
        int ret = 0;
        for (int i = 0, j = 1; i + 1 < arr.size(); i++) {
            while (j < arr.size() &&
                   (j <= i || !fracCmp(arr[i], arr[j], arr[x], arr[y]))) {
                j++;
            }
            ret += arr.size() - j;
        }
        return ret;
    }

    vector<int> kthSmallestPrimeFraction(vector<int>& arr, int k) {
        for (int x = 0; x + 1 < arr.size(); x++) {
            int ly = x + 1, hy = arr.size() - 1;
            while (ly < hy) {
                int my = (ly + hy) / 2 + 1;
                if (fracCnt(arr, x, my) >= k) {
                    ly = my;
                } else {
                    hy = my - 1;
                }
            }
            if (fracCnt(arr, x, ly) == k) {
                return vector<int>{ arr[x], arr[ly] };
            }
        }
        return vector<int>{ arr[0], arr[1] };
    }
};

COMMAND INTERFACE

↑ ↓ navigate · Enter execute · Esc exit · try “whoami”

Loading filesystem…

:help aguang.xyz

A personal website disguised as an operating system.

Ctrl / Cmd + K
Command palette + full-text search
Tab / Shift + Tab
Move between links and controls
Enter
Open a focused link or search result
↑ / ↓ in search
Navigate search results
In a directory filter
Enter/Done or ↓ focuses a result; Esc clears the filter
Esc
Clear a search or close a window