Pagini recente » Cod sursa (job #611237) | Cod sursa (job #2777950) | Cod sursa (job #641031) | Cod sursa (job #2067549) | Cod sursa (job #1982933)
#include <bits/stdc++.h>
using namespace std;
ifstream in ( "euro.in" );
ofstream out( "euro.out" );
class LinearFunction {
public:
static const int INF = numeric_limits<int> :: max();
int a; long long b;
mutable long double point;
LinearFunction( int _a, long long _b ) {
this -> a = _a;
this -> b = _b;
}
LinearFunction( int _a, long long _b, long double _point ) {
this -> a = _a; this -> b = _b;
this -> point = _point;
}
bool operator < ( const LinearFunction &other ) const {
if( other.a == INF )
return this -> point < other.point;
return make_pair( this -> a, this -> b ) <
make_pair( other.a , other.b );
}
long long getValue( int x ) const {
return 1LL * this -> a * x + this -> b;
}
};
class ConvexHullTrick : public set<LinearFunction> {
private:
static const int INF = numeric_limits<int> :: max();
inline bool bad( iterator it ) {
if( next(it) == end() )
return false;
if( it == begin() )
return false;
set<LinearFunction> :: iterator nxt, prv;
nxt = next(it); prv = prev(it);
return 1.0 * ( prv -> b - nxt -> b ) * ( nxt -> a - it -> a ) >=
1.0 * ( it -> b - nxt -> b ) * ( nxt -> a - prv -> a );
}
inline void update( iterator it ) {
set<LinearFunction> :: iterator nxt = next(it);
if( nxt == end() )
it -> point = 1.0 * INF * INF;
else
it -> point = 1.0 * ( it -> b - nxt -> b ) / ( nxt -> a - it -> a );
return;
}
public:
void insertLinearFunction( LinearFunction function ) {
if( insert( function ).second == false )
return;
set<LinearFunction> :: iterator it = find( function );
if( next(it) != end() && next(it) -> a == it -> a && next(it) -> b < it -> b )
erase(it), it = end();
else
if( it != begin() && prev(it) -> a == it -> a && prev(it) -> b < it -> b )
erase(it), it = end();
else
if( it != end() && bad(it) == true )
erase(it), it = end();
if( it == end() )
return;
while( next(it) != end() && bad( next(it) ) )
erase( next(it) );
while( it != begin() && bad( prev(it) ) )
erase( prev(it) );
update(it);
if( it != begin() )
update( prev(it) );
return;
}
long long findLinearFunction( int x ) {
return lower_bound( LinearFunction( INF, 0, x ) ) -> getValue( x );
}
} data;
int main( void ) {
int n, t;
in >> n >> t;
data.insertLinearFunction( LinearFunction( 0, 0 ) );
for( int i = 1, s = 0; i <= n; i ++ ) {
int x;
in >> x; s += x;
long long dp = data.findLinearFunction( i ) + 1LL * s * i - t;
data.insertLinearFunction( LinearFunction( -s, dp ) );
if( i == n )
out << dp << endl;
}
return 0;
}