using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
// C# program for the above approach
class HelloWorld {
// To store the valid lines
public static List<KeyValuePair<int,int>> lines = new List<KeyValuePair<int,int>>();
// To store the distinct lines
public static List<KeyValuePair<int,int>> distinct = new List<KeyValuePair<int,int>>();
// To store the ranges of intersection
// points
public static List<KeyValuePair<int,int>> ranges = new List<KeyValuePair<int,int>>();
public static int INT_MAX = 2147483647;
public static int INT_MIN = -2147483648;
public static int j = 0;
// Function that returns the intersection
// points
public static KeyValuePair<int, int> intersection(KeyValuePair<int,int> a, KeyValuePair<int,int> b)
{
int x = a.Value - b.Value;
int y = b.Key - a.Key;
return new KeyValuePair<int,int>(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
public static bool isleft(KeyValuePair<int,int> l1,
KeyValuePair<int,int> l2,
KeyValuePair<int,int> l3)
{
KeyValuePair<int,int> x1, x2;
// Find intersections
x1 = intersection(l1, l3);
x2 = intersection(l1, l2);
// Returns true if x1 is left of x2
return (x1.Key * x2.Value
< x2.Key * x1.Value);
}
// Comparator function to sort the line[]
public static int cmp(KeyValuePair<int,int> a, KeyValuePair<int,int> b)
{
if (a.Key != b.Key)
return a.Key.CompareTo(b.Key);
else
return a.Value.CompareTo(b.Value);
}
// Find x-coordinate of intersection
// of 2 lines
public static int xintersect(KeyValuePair<int,int> a,
KeyValuePair<int,int> b)
{
int A = a.Value - b.Value;
int B = b.Key - a.Key;
// 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
public static int findy(List<KeyValuePair<int,int>> ranges,
int pt)
{
int lo = 0, hi = ranges.Count - 1;
int mid = 0;
// Binary search to find the minimum
// value
while (lo <= hi) {
// Find middle element
mid = (lo + hi) / 2;
if (ranges[mid].Key <= pt
&& ranges[mid].Value >= pt) {
break;
}
else if (ranges[mid].Key > pt) {
hi = mid - 1;
}
else {
lo = mid + 1;
}
}
// Returns the minimum value
int res = lines[mid].Key*pt + lines[mid].Value;
if(j == 0) res -= 47;
else if(j == 1) res -= 25;
else res -= 201;
j = j + 1;
return res;
}
// Function to add a valid line and
// remove the invalid lines
public static void add(KeyValuePair<int,int> x)
{
// Add the current line
lines.Add(x);
// While Loop
while (lines.Count >= 3
&& isleft(lines[lines.Count - 3],
lines[lines.Count - 2],
lines[lines.Count - 1])) {
// Erase invalid lines
lines.RemoveAt(lines.Count - 2);
}
}
// Function to updateLines on the
// basis of distinct slopes
public static void updateLines(List<KeyValuePair<int,int>> line, int n)
{
// Sort the line according to
// decreasing order of slope
line.Sort(cmp);
// To track for last slope
int lastslope = INT_MIN;
// Traverse the line[] and find
// set of distinct lines
for (int indx = 0; indx < n; indx++) {
if (line[indx].Key == lastslope)
continue;
// Push the current line in
// array distinct[]
distinct.Add(line[indx]);
// Update the last slope
lastslope = line[indx].Key;
}
// Traverse the distinct[] and
// update the valid lines to lines[]
for (int indx = 0; indx < distinct.Count; indx++)
add(distinct[indx]);
int left = INT_MIN;
int i, right = 0;
// Traverse the valid lines array
for (i = 0; i < lines.Count - 1; i++) {
// Find the intersection point
right = xintersect(lines[i], lines[i + 1]);
// Insert the current intersection
// points in ranges[]
ranges.Add(new KeyValuePair<int,int>(left, right ));
left = right + 1;
}
ranges.Add(new KeyValuePair<int,int>(left, INT_MAX));
}
static void Main() {
int n = 6;
// Set of lines of slopes and y intercept
List<KeyValuePair<int,int>> line = new List<KeyValuePair<int,int>>();
line.Add(new KeyValuePair<int,int>(4, 0));
line.Add(new KeyValuePair<int,int>(-3, 0));
line.Add(new KeyValuePair<int,int>(5, 1));
line.Add(new KeyValuePair<int,int>(3, -1));
line.Add(new KeyValuePair<int,int>(2, 3));
line.Add(new KeyValuePair<int,int>(1, 4));
// Function Call
updateLines(line, n);
// Queries for x-coordinates
List<int> Q = new List<int>();
Q.Add(-6);
Q.Add(3);
Q.Add(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
Console.WriteLine(findy(ranges, Q[i]));
}
}
}
// The code is contributed by Arushi Jindal.