Pagini recente » Cod sursa (job #214847) | Cod sursa (job #1306078) | Cod sursa (job #397598) | Cod sursa (job #1009679) | Cod sursa (job #2156645)
#include <bits/stdc++.h>
using namespace std;
using T = long long;
const T is_query = numeric_limits<T>::min();
struct Line {
T a, b;
mutable function<const Line *()> succ;
T Eval(T x) const { return a * x + b; }
bool operator<(const Line &rhs) const {
if (rhs.b != is_query) return a < rhs.a;
const Line *s = succ();
if (!s) return 0;
return Eval(rhs.a) < s->Eval(rhs.a);
}
};
struct ConvexSet : public multiset<Line> {
bool bad(iterator y) {
auto z = next(y);
if (y == begin()) {
return (z == end() ? 0 : y->a == z->a && y->b <= z->b);
}
auto x = prev(y);
if (z == end()) return y->a == x->a && y->b <= x->b;
return (x->b - y->b) * (z->a - y->a) >= (y->b - z->b) * (y->a - x->a);
}
void InsertLine(T a, T b) {
auto y = insert({a, b});
y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };
if (bad(y)) { erase(y); return; }
while (next(y) != end() && bad(next(y))) erase(next(y));
while (y != begin() && bad(prev(y))) erase(prev(y));
}
T Eval(T x) { return lower_bound({x, is_query})->Eval(x); }
};
int main() {
freopen("euro.in", "r", stdin);
freopen("euro.out", "w", stdout);
int n, t;
cin >> n >> t;
// dp[i] = max_j(dp[j] + (gain[i] - gain[j]) * i - t)
// dp[i] = max_j(dp[j] - gain[j] * i + gain[i] * i - t)
// dp[i] = gain[i] * i - t + max_j(dp[j] - gain[j] * i)
// solution: keep stack of linear functions of type
// -gain[j] * X + dp[j]
// no monotony -> need set
ConvexSet ct;
ct.InsertLine(0, 0);
long long ans = 0, gain = 0;
for (int i = 1; i <= n; ++i) {
int x; cin >> x; gain += x;
ans = ct.Eval(i) + gain * i - t;
ct.InsertLine(-gain, ans);
}
cout << ans << endl;
return 0;
}