Pagini recente » Cod sursa (job #2030042) | Cod sursa (job #2999538) | Cod sursa (job #2916779) | Cod sursa (job #2849913) | Cod sursa (job #2716328)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 2e18;
bool QUERY;
struct Line {
mutable ll a, b, p;
ll Eval(ll x) const { return a * x + b; }
bool operator<(const Line& o) const {
return QUERY ? p < o.p : a < o.a;
}
};
struct LineContainer : multiset<Line> {
ll div(ll a, ll b) { return a / b - (a % b < 0); }
void InsertLine(ll a, ll b) {
auto isect = [&](auto x, auto y) {
if (y == end()) return x->p = INF, false;
if (x->a == y->a) x->p = x->b > y->b ? INF : -INF;
else x->p = div(x->b - y->b, y->a - x->a);
return x->p >= y->p;
};
auto nx = insert({a, b, 0}), it = nx++, pv = it;
while (isect(it, nx)) nx = erase(nx);
if (pv != begin() && isect(--pv, it))
isect(pv, it = erase(it));
while ((it = pv) != begin() && (--pv)->p >= it->p)
isect(pv, erase(it));
}
ll EvalMax(ll x) {
assert(!empty());
QUERY = 1; auto it = lower_bound({0,0,x}); QUERY = 0;
return it->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
LineContainer 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.EvalMax(i) + gain * i - t;
ct.InsertLine(-gain, ans);
}
cout << ans << endl;
return 0;
}