import java.io.*; import java.util.*; /** * Covered Walkway * @author vanb * * This problem would be pretty easy, if it weren't for the size of the data sets. * If the data sets were small, a simple DP solution would suffice: * * Let best[i] be the best you can do covering A[0]..A[i]. * Then best[i] = MIN{best[j] + C + (A[i]-A[j+1])^2} for jx. * Once k becomes better, we never have to look at j again. * * We'll maintain a linked list of breakpoints, and remember their m's and b's. * We'll walk forward through this list, and never have to go back. Any new * breakpoint we add will have the most negative slope, so it will need to be * added to the end of the list. But, it may shunt off some other breakpoints. * So, we'll add it to the end of the list and remove any breakpoints that it * shunts off. If we do that, then we won't have to go through the whole list to find * the minimum. Every breakpoint will either get walked over once, or shunted off once. * Either way, we've reduced that process of finding the minimum to O(n) prorated * over the entire algorithm, making the whole thing O(n). * */ public class covered { public Scanner sc; public PrintStream ps; public static final int MAX = 1000000; /** * This represents a breakpoint between A[i-1] and A[i] * * @author vanb */ public class Breakpoint { // i public int index; // Slope, y-intercept of the line public long m, b; // Doubly linked list public Breakpoint next, prev; /** * Build a breakpoint * * @param i Index * @param x A[i] * @param best best[i-1] */ public Breakpoint( int i, long x, long best ) { index = i; m = -2L * x; b = x*x + best; next = prev = null; } /** * A cusp between two breakpoints. This is the point where * 'this' stops being best and 'bp' starts being best. * That's just the intersection of the two lines. * This method returns the smallest integer greater than * or equal to the cusp. * * @param bp Another Breakpoint to compare * @return The smallest integer greater than or equal to the cusp. */ public long cusp( Breakpoint bp ) { // we're looking for the intersection of two lines, // where m1*x+b1 = m2*x+b2. A little algebra yields // x = (b1-b2)/(m2-m1). long numerator = bp.b - b; long denominator = m - bp.m; long quotient = numerator / denominator; long remainder = numerator % denominator; return remainder==0 ? quotient : quotient+1; } /** * The value of y at any given point x on the line * representing this breakpoint. The smaller y, * the better this breakpoint is. * * @param x X * @return Y */ public long y( long x ) { return m*x + b; } } /** * Do it! * @throws Exception */ public void doit() throws Exception { sc = new Scanner( System.in ); //new File( "covered.in" ) ); ps = System.out; //new PrintStream( new FileOutputStream( "covered.out" ) ); // Allocate arrays beforehand long a[] = new long[MAX]; long best[] = new long[MAX]; for(;;) { int n = sc.nextInt(); long c = sc.nextLong(); if( n==0 ) break; Breakpoint head=null, tail=null; a[0] = sc.nextLong(); // We can cover A[0] with cost C, and that's all we can do. best[0] = c; head = tail = new Breakpoint( 0, a[0], 0L ); for( int i=1; i= tail.y( x ) ) break; tail = tail.prev; } // Put this new BP at the tail newbp.prev = tail; tail.next = newbp; tail = newbp; // Did this go so far as to shunt off the head? if( tail.prev == head && head.y( a[i] )>=tail.y( a[i] ) ) { head = tail; head.prev = null; } } ps.println( best[n-1] ); } } /** * Main * @param args Unused * @throws Exception */ public static void main( String[] args ) throws Exception { new covered().doit(); } }