Pagini recente » Cod sursa (job #1573257) | Cod sursa (job #1599306) | Cod sursa (job #3178258) | Cod sursa (job #1940690) | Cod sursa (job #847482)
Cod sursa(job #847482)
#include <cstdio>
#include <cmath>
#include <cassert>
#include <deque>
#include <algorithm>
using namespace std;
typedef long long LL;
const int MaxN = 50000;
const LL oo = 1LL<<60;
struct Line {
LL m, n;
Line() {}
Line(const LL m, const LL n) {
this->m = m, this->n = n;
}
LL Value(const LL x) const {
return m * x + n;
}
static LL Intersect(const Line &L1, const Line &L2) {
if (L1.m > L2.m)
return oo;
if (L1.m == L2.m)
return L1.n < L2.n ? 0 : oo;
return static_cast<int>(ceil(1.0 * (L2.n - L1.n) / (L1.m - L2.m)));
}
};
Line L[MaxN];
int N;
LL T, Sum[MaxN], DP[MaxN], Best[MaxN];
deque<int> Deq;
void PrintDeq() {
for (size_t i = 0; i < Deq.size(); ++i)
fprintf(stderr, "%d ", Deq[i]);
fprintf(stderr, "\n");
}
void Solve() {
L[0] = Line(0, 0);
Deq.push_back(0);
for (int i = 1; i <= N; ++i) {
for (; Deq.size() > 1 && Best[Deq[1]] <= i; Deq.pop_front());
DP[i] = L[Deq.front()].Value(i) + Sum[i] * i - T;
L[i] = Line(-Sum[i], DP[i]);
for (; Deq.size() > 1 && Line::Intersect(L[Deq.back()], L[i]) <= Best[Deq.back()]; Deq.pop_back());
Best[i] = Line::Intersect(L[Deq.back()], L[i]);
Deq.push_back(i);
PrintDeq();
}
}
void Read() {
assert(freopen("euro.in", "r", stdin));
assert(scanf("%d %lld", &N, &T) == 2);
for (int i = 1; i <= N; ++i) {
assert(scanf("%lld", &Sum[i]) == 1);
Sum[i] += Sum[i - 1];
}
}
void Print() {
assert(freopen("euro.out", "w", stdout));
printf("%lld\n", DP[N]);
}
int main() {
Read();
Solve();
Print();
return 0;
}