Pagini recente » Cod sursa (job #2267629) | Cod sursa (job #206823) | Cod sursa (job #2856588) | Cod sursa (job #1080249) | Cod sursa (job #1198947)
#include <cmath>
#include <fstream>
#include <set>
#include <algorithm>
using namespace std;
typedef long long int64;
const double oo = 1e15;
const double EPS = 1e-9;
const double QUERY_M = 1e17;
class Line {
public:
double m, n;
mutable double x;
Line(const double _m, const double _n):
m(_m),
n(_n) {}
double Value(const double where) const {
return m * where + 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;
}
};
class LowerEnvelope: public multiset<Line> {
public:
void InsertLine(const Line &l) {
iterator x = insert(l);
if (Bad(x)) {
erase(x);
return;
}
while (x != begin() && Bad(prev(x)))
erase(prev(x));
while (next(x) != end() && Bad(next(x)))
erase(next(x));
if (x != begin())
Update(prev(x));
Update(x);
}
double MaxValue(const double x) const {
return lower_bound(Line(QUERY_M, x))->Value(x);
}
private:
bool Bad(iterator y) const {
if (y == end())
return false;
if (y == begin()) {
iterator z = next(y);
if (z == end())
return false;
return abs(y->m - z->m) < EPS && y->n < z->n;
}
iterator x = prev(y), z = next(y);
if (z == end())
return abs(x->m - y->m) < EPS && y->n < x->n;
return (y->n - x->n) / (x->m - y->m) - (z->n - y->n) / (y->m - z->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;
}