Pagini recente » Cod sursa (job #3356816) | Cod sursa (job #3303570) | Cod sursa (job #3334024) | Cod sursa (job #1010048) | Cod sursa (job #3350087)
#include <iostream>
#include <fstream>
#include <cassert>
#include <algorithm>
#include <vector>
#include <random>
template<class T> using vec = std::vector<T>;
using ll = long long;
constexpr ll INF = 1e18;
struct Line {
ll ct, slope;
Line(): ct(0), slope(0) {}
Line( ll ct, ll slope ): ct(ct), slope(slope) {}
ll operator ()( ll x ) const { return ct + x * slope; }
};
struct LiChao {
int n;
vec<Line> aint;
LiChao( int n ): n(n), aint(2 * n - 1, Line()) {}
void push( const Line &L ) { push( 0, 0, n - 1, L ); }
void push( int root, int rl, int rr, Line L ) {
int mij = (rl + rr) >> 1;
if( L(mij) > aint[root](mij) )
std::swap( L, aint[root] );
if( rl == rr ) return;
int state = 2 * int(L(rl) > aint[root](rl)) + int(L(rr) > aint[root](rr));
if( state == 1 ) push( root + 2 * (mij+1 - rl), mij+1, rr, L );
else if( state == 2 ) push( root + 1, rl, mij, L );
}
ll query( int idx ) const {
ll ret = aint[0]( idx );
int root = 0, rl = 0, rr = n - 1;
while( rl < rr ){
int mij = (rl + rr) >> 1;
if( idx <= mij ) { root += 1; rr = mij; }
else { root = root + 2 * (mij+1 - rl); rl = mij + 1; }
ret = std::max( ret, aint[root]( idx ) );
}
return ret;
}
};
int main() {
std::ifstream fin("euro.in");
std::ofstream fout("euro.out");
int n, fee;
fin >> n >> fee;
vec<int> costs(n);
for( int &x : costs ) fin >> x;
vec<ll> sp(n + 1, 0);
for( int i = 0; i < n; i++ )
sp[i + 1] = sp[i] + costs[i];
// dp[i] = -fee + max{ dp[j] + (sp[i] - sp[j]) * i }
// dp[i] = -fee + sp[i] * i + max{ (dp[j]) + i * (-sp[j]) }
LiChao zile(n + 1);
ll ret = 0;
for( int i = 1; i <= n; i++ ){
ret = sp[i] * (ll)i + zile.query( i ) - fee;
zile.push( Line(ret, -sp[i]) );
}
fout << ret << std::endl;
return 0;
}