Pagini recente » Cod sursa (job #2298455) | Cod sursa (job #1986571) | Cod sursa (job #1377199) | Cod sursa (job #1060621) | Cod sursa (job #1269004)
#include <cmath>
#include <fstream>
#include <set>
#include <algorithm>
using namespace std;
typedef long long int64;
const double EPS = 1e-9;
const double oo = 1e15;
class Line {
public:
static const double QUERY_M;
double m, n;
mutable double x;
Line(const double _m, const double _n):
m(_m),
n(_n),
x(oo) {}
double Value(const double x) const {
return m * x + n;
}
bool operator<(const Line &other) const {
if (abs(other.m - QUERY_M) < EPS)
return x < other.n;
if (abs(m - other.m) < EPS)
return n > other.n;
return m < other.m;
}
};
const double Line::QUERY_M = 1e17;
class LowerEnvelope: public multiset<Line> {
public:
void InsertLine(const Line &line) {
iterator l = insert(line);
if (Bad(l)) {
erase(l);
return;
}
while (l != begin() && Bad(prev(l)))
erase(prev(l));
while (next(l) != end() && Bad(next(l)))
erase(next(l));
if (l != begin())
Update(prev(l));
Update(l);
}
double MaxValue(const double x) const {
return lower_bound(Line(Line::QUERY_M, x))->Value(x);
}
private:
bool Bad(iterator y) const {
if (y == end())
return false;
iterator z = next(y);
if (y == begin()) {
if (z == end())
return false;
return abs(y->m - z->m) < EPS && y->n - z->n < EPS;
}
iterator x = prev(y);
if (z == end())
return abs(x->m - y->m) < EPS && y->n - x->n < EPS;
return (y->n - x->n) * (y->m - z->m) - (z->n - y->n) * (x->m - y->m) > -EPS;
}
void Update(iterator x) {
if (x == end())
return;
iterator y = next(x);
if (y == end())
x->x = oo;
else
x->x = (y->n - x->n) / (x->m - y->m);
}
};
inline int64 Round(const double value) {
return int64(value + 0.5);
}
int main() {
ifstream cin("euro.in");
ofstream cout("euro.out");
int n;
int64 t, sum = 0, dp = 0;
cin >> n >> t;
LowerEnvelope envelope = LowerEnvelope();
envelope.InsertLine(Line(0, 0));
for (int i = 1; i <= n; ++i) {
int64 value;
cin >> value;
sum += value;
dp = Round(envelope.MaxValue(i)) + sum * i - t;
envelope.InsertLine(Line(-sum, dp));
}
cout << dp << "\n";
cin.close();
cout.close();
return 0;
}