Given **N** lines in a plane in the form of a 2D array **arr[][]** such that each row consists of 2 integers(say **m & c**) where **m** is the slope of the line and **c** is the **y-intercept** of that line. You are given **Q** queries each consist of **x-ordinates**. The task is to find the minimum possible **y-coordinate** corresponding to each line for each query.

**Examples:**

Input:arr[][] = { { 4, 0 }, { -3, 0 }, { 5, 1 }, { 3, -1 },{ 2, 3 }, { 1, 4 } } and Q[] = {-6, 3, 100}

Output:

-29

-9

-300

Explanation:

The minimum value for x = -6 from the given set of lines is -29.

The minimum value for x = 3 from the given set of lines is -9.

The minimum value for x = -100 from the given set of lines is -300.

**Naive Approach:** The naive approach is to find the y-coordinates for each line and the minimum of all the y-coordinates will give the minimum y-coordinate value. Repeating the above for all the queries gives the time complexity of **O(N*Q)**.

**Efficient Approach:**

__Observations__

**L1**an**L2**are two lines and they intersect at**(x1, y1)**, if**L1**is lower than before**x = x1**then**L2**will be lower than**L1**after**x = x1**. This implies that the lines gives lower value for some continuous ranges.**L4**is the line which is parallel to x axis, which is constant as**y = c4**and never gives minimum correspoding to all the lines.- Therefore, the line with higher slopes give minimum value at lower x-coordinates and maximum value at higher x-coordinates. For Examples if slope
**(L1)**> slope**(L2)**and they intersect at**(x1, y1)**then for**x < x1**line**L1**gives minimum value and for**x > x1**line**L2**gives minimum value. - For lines
**L1, L2 and L3,**if**slope(L1) > slope(L2) > slope(L3)**and if intersection point of**L1 and L3**is below than**L1 and L2**, then we can neglact the line**L2**as it cannot gives minimum value for any x-coordinates.

On the basis of the above observations following are the steps:

- Sort the slopes in decreasing order of slope.
- From a set of lines having same slopes, keep the line with least
**y-intercept**value and discard all the remaining lines with same slope. - Add first two lines to set of valid lines and find the intersection points(say
**(a, b)**). - For the next set of remaining lines do the following:
- Find the intersection point(say
**(c, d)**) of the second last line and the current line. - If
**(c, d)**is lower than**(a, b)**, then remove the last line inserted from the valid lines as it s no longer valid due to current line.

- Find the intersection point(say
- Repeat the above steps to generate all the valid lines set.
- Now we have valid lines set and each line in the valid lines set forms the minimum in a continuous range in increasing order i.e.,
**L1**is minimum in range**[a, b]**and L2 in range**[b, c]**. - Perform Binary Search on ranges[] to find the minimum
**y-coordinates**for each queries of**x-cordinates**.

Below is the implementation of the above approach:

`// C++ program for the above approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// To store the valid lines ` `vector<pair<` `int` `, ` `int` `> > lines; ` ` ` `// To store the distinct lines ` `vector<pair<` `int` `, ` `int` `> > distinct; ` ` ` `// To store the ranges of intersection ` `// points ` `vector<pair<` `int` `, ` `int` `> > ranges; ` ` ` `// Function that returns the intersection ` `// points ` `pair<` `int` `, ` `int` `> intersection(pair<` `int` `, ` `int` `> a, ` ` ` `pair<` `int` `, ` `int` `> b) ` `{ ` ` ` `int` `x = a.second - b.second; ` ` ` `int` `y = b.first - a.first; ` ` ` `return` `{ x, y }; ` `} ` ` ` `// Function to see if a line is eligible ` `// or not. ` `// L3 is the current line being added and ` `// we check eligibility of L2 ` `bool` `isleft(pair<` `int` `, ` `int` `> l1, ` ` ` `pair<` `int` `, ` `int` `> l2, ` ` ` `pair<` `int` `, ` `int` `> l3) ` `{ ` ` ` `pair<` `int` `, ` `int` `> x1, x2; ` ` ` ` ` `// Find intersections ` ` ` `x1 = intersection(l1, l3); ` ` ` `x2 = intersection(l1, l2); ` ` ` ` ` `// Returns true if x1 is left of x2 ` ` ` `return` `(x1.first * x2.second ` ` ` `< x2.first * x1.second); ` `} ` ` ` `// Comparator function to sort the line[] ` `bool` `cmp(pair<` `int` `, ` `int` `> a, pair<` `int` `, ` `int` `> b) ` `{ ` ` ` `if` `(a.first != b.first) ` ` ` `return` `a.first > b.first; ` ` ` `else` ` ` `return` `a.second < b.second; ` `} ` ` ` `// Find x-coordinate of intersection ` `// of 2 lines ` `int` `xintersect(pair<` `int` `, ` `int` `> a, ` ` ` `pair<` `int` `, ` `int` `> b) ` `{ ` ` ` ` ` `int` `A = a.second - b.second; ` ` ` `int` `B = b.first - a.first; ` ` ` ` ` `// Find the x coordinate ` ` ` `int` `x = A / B; ` ` ` ` ` `if` `(A * B < 0) ` ` ` `x -= 1; ` ` ` ` ` `return` `x; ` `} ` ` ` `// Function to returns the minimum ` `// possible value for y ` `int` `findy(vector<pair<` `int` `, ` `int` `> >& ranges, ` ` ` `int` `pt) ` `{ ` ` ` `int` `lo = 0, hi = ranges.size() - 1; ` ` ` `int` `mid = 0; ` ` ` ` ` `// Binary search to find the minimum ` ` ` `// value ` ` ` `while` `(lo <= hi) { ` ` ` ` ` `// Find middle element ` ` ` `mid = (lo + hi) / 2; ` ` ` ` ` `if` `(ranges[mid].first <= pt ` ` ` `&& ranges[mid].second >= pt) { ` ` ` `break` `; ` ` ` `} ` ` ` `else` `if` `(ranges[mid].first > pt) { ` ` ` `hi = mid - 1; ` ` ` `} ` ` ` `else` `{ ` ` ` `lo = mid + 1; ` ` ` `} ` ` ` `} ` ` ` ` ` `// Returns the minimum value ` ` ` `return` `lines[mid].first * pt + lines[mid].second; ` `} ` ` ` `// Function to add a valid line and ` `// remove the invalid lines ` `void` `add(pair<` `int` `, ` `int` `> x) ` `{ ` ` ` `// Add the current line ` ` ` `lines.push_back(x); ` ` ` ` ` `// While Loop ` ` ` `while` `(lines.size() >= 3 ` ` ` `&& isleft(lines[lines.size() - 3], ` ` ` `lines[lines.size() - 2], ` ` ` `lines[lines.size() - 1])) { ` ` ` ` ` `// Erase invalid lines ` ` ` `lines.erase(lines.end() - 2); ` ` ` `} ` `} ` ` ` `// Function to updateLines on the ` `// basis of distinct slopes ` `void` `updateLines(pair<` `int` `, ` `int` `> line[], ` ` ` `int` `n) ` `{ ` ` ` ` ` `// Sort the line according to ` ` ` `// decreasing order of slope ` ` ` `sort(line, line + n, cmp); ` ` ` ` ` `// To track for last slope ` ` ` `int` `lastslope = INT_MIN; ` ` ` ` ` `// Traverse the line[] and find ` ` ` `// set of distinct lines ` ` ` `for` `(` `int` `i = 0; i < n; i++) { ` ` ` ` ` `if` `(line[i].first == lastslope) ` ` ` `continue` `; ` ` ` ` ` `// Push the current line in ` ` ` `// array distinct[] ` ` ` `distinct.push_back(line[i]); ` ` ` ` ` `// Update the last slope ` ` ` `lastslope = line[i].first; ` ` ` `} ` ` ` ` ` `// Traverse the distinct[] and ` ` ` `// update the valid lines to lines[] ` ` ` `for` `(` `int` `i = 0; i < distinct.size(); i++) ` ` ` `add(distinct[i]); ` ` ` ` ` `int` `left = INT_MIN; ` ` ` `int` `i, right = 0; ` ` ` ` ` `// Traverse the valid lines array ` ` ` `for` `(i = 0; i < lines.size() - 1; i++) { ` ` ` ` ` `// Find the intersection point ` ` ` `int` `right = xintersect(lines[i], ` ` ` `lines[i + 1]); ` ` ` ` ` `// Insert the current intersection ` ` ` `// points in ranges[] ` ` ` `ranges.push_back({ left, right }); ` ` ` ` ` `left = right + 1; ` ` ` `} ` ` ` ` ` `ranges.push_back({ left, INT_MAX }); ` `} ` ` ` `// Driver Code ` `int` `main() ` `{ ` ` ` `int` `n = 6; ` ` ` ` ` `// Set of lines of slopes and y intercept ` ` ` `pair<` `int` `, ` `int` `> line[] = { { 4, 0 }, { -3, 0 }, ` ` ` `{ 5, 1 }, { 3, -1 }, ` ` ` `{ 2, 3 }, { 1, 4 } }; ` ` ` ` ` `// Function Call ` ` ` `updateLines(line, n); ` ` ` ` ` `// Queries for x-coordinates ` ` ` `int` `Q[] = { -6, 3, 100 }; ` ` ` ` ` `// Traverse Queries to find minimum ` ` ` `// y-coordinates ` ` ` `for` `(` `int` `i = 0; i < 3; i++) { ` ` ` ` ` `// Use Binary Search in ranges ` ` ` `// to find the minimum y-coordinates ` ` ` `cout << findy(ranges, Q[i]) ` ` ` `<< endl; ` ` ` `} ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

-29 -9 -300

**Time Complexity:** *O(N + Q*log N)*, where N is the number of lines and Q is the numbers of queries.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.

## Recommended Posts:

- Find minimum value of y for the given x values in Q queries from all the given set of lines
- Maximum distance between two points in coordinate plane using Rotating Caliper's Method
- Shortest distance between a Line and a Point in a 3-D plane
- Total number of triangles formed when there are H horizontal and V vertical lines
- Find minimum steps required to reach the end of a matrix | Set - 1
- Find Maximum and Minimum element in a Set in C++ STL
- Find minimum steps required to reach the end of a matrix | Set 2
- Van Emde Boas Tree | Set 2 | Insertion, Find, Minimum and Maximum Queries
- Find the minimum dominating set of a Binary tree
- Find the node whose sum with X has minimum set bits
- Maximum and minimum of an array using minimum number of comparisons
- Remove minimum numbers from the array to get minimum OR value
- Find the minimum element in a sorted and rotated array
- Find minimum time to finish all jobs with given constraints
- Find minimum value to assign all array elements so that array product becomes greater
- Find the node whose xor with x gives minimum value
- Find minimum speed to finish all Jobs
- Find the minimum positive integer such that it is divisible by A and sum of its digits is equal to B
- Find minimum x such that (x % k) * (x / k) == n
- Find the maximum possible value of the minimum value of modified array

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.