# Find the maximum value of Y for a given X from given set of lines

Given a set of lines represented by a 2-dimensional array arr consisting of slope(m) and intercept(c) respectively and Q queries such that each query contains a value x. The task is to find the maximum value of y for each value of x from all the given a set of lines.

The given lines are represented by the equation y = m*x + c.

Examples:

Input: arr[] ={ {1, 1}, {0, 0}, {-3, 3} }, Q = {-2, 2, 1}
Output: 9, 3, 2
For query x = -2, y values from the equations are -1, 0, 9. So the maximum value is 9
Similarly, for x = 2, y values are 3, 0, -3. So the maximum value is 3
And for x = 1, values of y = 2, 0, 0. So the maximum value is 2.

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

Naive Approach: The naive approach is to substitute the values of x in every line and compute the maximum 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 maximal 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 maximum 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 ` `using` `namespace` `std; ` ` `  `struct` `Line { ` `    ``int` `m, c; ` ` `  `public``: ` `    ``// Sort the line in decreasing ` `    ``// order of their slopes ` `    ``bool` `operator<(Line l) ` `    ``{ ` ` `  `        ``// If slopes aren't 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 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 maximum value ` `    ``// of y for the given x coordinate ` `    ``int` `maxQuery(``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, 1 }; ` `    ``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.maxQuery(x) << endl; ` `    ``} ` ` `  `    ``return` `0; ` `} `

Output:

```9
3
2
```

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.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

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.