Given a 2 dimensional array **arr[][]** consisting of **slope(m)** and **intercept(c)** for large number of lines of the form **y = mx + c** and **Q** queries such that each query contains a value **x**. The task is to find the minimum value of **y** for the given **x** values from all the given set of lines.

**Examples:**

Input:arr[][] ={ {1, 1}, {0, 0}, {-3, 3} }, Q = {-2, 2, 0}

Output:-1, -3, 0

Explanation:

For query x = -2, y values from the equations are -1, 0, 9. So the minimum value is -1

Similarly, for x = 2, y values are 3, 0, -3. So the minimum value is -3

And for x = 0, values of y = 1, 0, 3 so min value is 0.

Input:arr[][] ={ {5, 6}, {3, 2}, {7, 3} }, Q = { 1, 2, 30 }

Output:5, 8, 92

**Naive Approach:** The naive approach is to substitute the values of x in every line and compute the minimum of all the lines. For each query, it will take O(N) time and so the complexity of the solution becomes **O(Q * N)** where N is the number of lines and Q is the number of queries.

**Efficient approach:** The idea is to use convex hull trick:

- From the given set of lines, the lines which carry no significance (for any value of x they never give the minimal value y) can be found and deleted thereby reducing the set.
- Now, if the ranges (l, r) can be found where each line gives the minimum value, then each query can be answered using binary search.
- Therefore, a sorted vector of lines with decreasing order of slopes is created and the lines are inserted in decreasing order of the slopes.

Below is the implementation of the above approach:

`// C++ implementation of the above approach ` ` ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `struct` `Line { ` ` ` `int` `m, c; ` ` ` `public` `: ` ` ` `// Sort the line in decreasing ` ` ` `// order of their slopes ` ` ` `bool` `operator<(Line l) ` ` ` `{ ` ` ` ` ` `// If slopes arent equal ` ` ` `if` `(m != l.m) ` ` ` `return` `m > l.m; ` ` ` ` ` `// If the slopes are equal ` ` ` `else` ` ` `return` `c > l.c; ` ` ` `} ` ` ` ` ` `// Checks if line L3 or L1 is better than L2 ` ` ` `// Intersection of Line 1 and ` ` ` `// Line 2 has x-coordinate (b1-b2)/(m2-m1) ` ` ` `// Similarly for Line 1 and ` ` ` `// Line 3 has x-coordinate (b1-b3)/(m3-m1) ` ` ` `// Cross multiplication will give the below result ` ` ` `bool` `check(Line L1, Line L2, Line L3) ` ` ` `{ ` ` ` `return` `(L3.c - L1.c) * (L1.m - L2.m) ` ` ` `< (L2.c - L1.c) * (L1.m - L3.m); ` ` ` `} ` `}; ` ` ` `struct` `Convex_HULL_Trick { ` ` ` ` ` `// To store the lines ` ` ` `vector<Line> l; ` ` ` ` ` `// Add the line to the set of lines ` ` ` `void` `add(Line newLine) ` ` ` `{ ` ` ` ` ` `int` `n = l.size(); ` ` ` ` ` `// To check if after adding the new line ` ` ` `// whether old lines are ` ` ` `// losing significance or not ` ` ` `while` `(n >= 2 ` ` ` `&& newLine.check(l[n - 2], ` ` ` `l[n - 1], ` ` ` `newLine)) { ` ` ` `n--; ` ` ` `} ` ` ` ` ` `l.resize(n); ` ` ` ` ` `// Add the present line ` ` ` `l.push_back(newLine); ` ` ` `} ` ` ` ` ` `// Function to return the y coordinate ` ` ` `// of the specified line for the given coordinate ` ` ` `int` `value(` `int` `in, ` `int` `x) ` ` ` `{ ` ` ` `return` `l[in].m * x + l[in].c; ` ` ` `} ` ` ` ` ` `// Function to Return the minimum value ` ` ` `// of y for the given x coordinate ` ` ` `int` `minQuery(` `int` `x) ` ` ` `{ ` ` ` `// if there is no lines ` ` ` `if` `(l.empty()) ` ` ` `return` `INT_MAX; ` ` ` ` ` `int` `low = 0, high = (` `int` `)l.size() - 2; ` ` ` ` ` `// Binary search ` ` ` `while` `(low <= high) { ` ` ` `int` `mid = (low + high) / 2; ` ` ` ` ` `if` `(value(mid, x) > value(mid + 1, x)) ` ` ` `low = mid + 1; ` ` ` `else` ` ` `high = mid - 1; ` ` ` `} ` ` ` ` ` `return` `value(low, x); ` ` ` `} ` `}; ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `Line lines[] = { { 1, 1 }, ` ` ` `{ 0, 0 }, ` ` ` `{ -3, 3 } }; ` ` ` `int` `Q[] = { -2, 2, 0 }; ` ` ` `int` `n = 3, q = 3; ` ` ` `Convex_HULL_Trick cht; ` ` ` ` ` `// Sort the lines ` ` ` `sort(lines, lines + n); ` ` ` ` ` `// Add the lines ` ` ` `for` `(` `int` `i = 0; i < n; i++) ` ` ` `cht.add(lines[i]); ` ` ` ` ` `// For each query in Q ` ` ` `for` `(` `int` `i = 0; i < q; i++) { ` ` ` `int` `x = Q[i]; ` ` ` `cout << cht.minQuery(x) << endl; ` ` ` `} ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

**Output:**

-1 -3 0

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 y coordinates from set of N lines in a plane
- Find minimum possible values of A, B and C when two of the (A + B), (A + C) and (B + C) are given
- Find the minimum value of m that satisfies ax + by = m and all values after m also satisfy
- Sum of even values and update queries on an array
- Queries for counts of array elements with values in given range
- Range Queries to count the number of even parity values with updates
- Find the maximum value of Y for a given X from given set of lines
- Find whether only two parallel lines contain all coordinates points or not
- Python - Find the maximum number of triangles with given points on three lines
- Queries for elements having values within the range A to B in the given index range using Segment Tree
- Queries for the minimum element in an array excluding the given index range
- Maximum and Minimum Values of an Algebraic Expression
- Minimum length String with Sum of the alphabetical values of the characters equal to N
- Minimize the difference between the maximum and minimum values of the modified array
- Find the XOR of the elements in the given range [L, R] with the value K for a given set of queries
- Queries to find whether a number has exactly four distinct factors or not
- Find Number of Even cells in a Zero Matrix after Q queries
- Find sum of all unique elements in the array for K queries
- Find GCD of each subtree of a given node in an N-ary Tree for Q queries
- Find N values of X1, X2, ... Xn such that X1 < X2 < ... < XN and sin(X1) < sin(X2) < ... < sin(XN)

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.