Cod sursa(job #1982933)

Utilizator StarGold2Emanuel Nrx StarGold2 Data 20 mai 2017 17:36:53
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.13 kb
#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;
}