Pagini recente » Cod sursa (job #104771) | Cod sursa (job #194545) | Cod sursa (job #2033799) | Cod sursa (job #1040906) | Cod sursa (job #1949189)
#include <fstream>
#include <iostream>
#include <cstdlib>
#include <set>
using namespace std;
const long double INF = 1E18;
typedef long long int lint;
struct Line {
int A;
lint B;
mutable double x;
Line(int _A, lint _B):
A(_A), B(_B), x(INF) {}
Line(long double _x = 0):
A(-1), B(-1), x(_x) {}
lint getVal(int _x) const {
return 1LL * A * _x + B;
}
static bool slopeCompare;
friend bool operator<(const Line &a, const Line &b) {
if (slopeCompare) {
if (a.A != b.A)
return a.A < b.A;
else
return a.B < b.B;
}
else
return a.x < b.x;
}
friend long double intersect(const Line &a, const Line &b) {
return (a.B - b.B) / (a.A - b.A);
}
};
bool Line :: slopeCompare = true;
class Batch : set <Line> {
public:
void Insert(const Line &l) {
iterator it = insert(l).first;
if (bad(it)) {
erase(it);
return ;
}
while (next(it) != end() && bad(next(it)))
erase(next(it));
while (it != begin() && bad(prev(it)))
erase(prev(it));
refresh(it);
if (it != begin())
refresh(prev(it));
}
lint query(lint x) {
Line :: slopeCompare = false;
iterator it = lower_bound(Line(x));
Line :: slopeCompare = true;
return it -> getVal(x);
}
private:
bool bad(iterator it) {
iterator nxt = next(it);
if (nxt == end())
return false;
if (nxt -> A == it -> A)
return true;
if (it == begin())
return false;
iterator prv = prev(it);
return intersect(*prv, *nxt) >
intersect(*it, *nxt);
}
void refresh(iterator it) {
iterator nxt = next(it);
if (nxt == end())
it -> x = INF;
else
it -> x = intersect(*it, *nxt);
}
} batch;
const int NMAX = 35000 + 5;
int sp[NMAX];
lint dp[NMAX];
int main()
{
ifstream cin("euro.in");
ofstream cout("euro.out");
int N = 1000, T = 5;
cin >> N >> T;
for (int i = 1; i <= N; ++ i) {
cin >> sp[i];
//sp[i] = rand() % 200 - 100;
sp[i] += sp[i - 1];
}
for (int i = 1; i <= N; ++ i) {
batch.Insert(Line(-sp[i - 1], dp[i - 1]));
dp[i] = 1LL * sp[i] * i - T + batch.query(i);
}
cout << dp[N] << '\n';
return 0;
}