Pagini recente » Cod sursa (job #1006204) | Cod sursa (job #529467) | Cod sursa (job #259988) | Cod sursa (job #2154523) | Cod sursa (job #2716330)
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 2e18;
struct Line {
ll a, b;
ll Eval(ll x) { return a * x + b; }
};
struct ConvexTree {
struct Node { Line line; int l = -1, r = -1; };
vector<Node> T;
int root = -1;
const int MAX = 1e9; // Maximum abs(x)
int update(int node, int b, int e, Line& upd) {
if (node == -1) {
T.push_back({upd});
return T.size() - 1;
}
Line& cur = T[node].line;
int m = (b + e) / 2, l = T[node].l, r = T[node].r;
bool bb = upd.Eval(b) > cur.Eval(b);
bool bm = upd.Eval(m) > cur.Eval(m);
if (bm) swap(cur, upd);
if (e - b == 1) { /* do nothing */ }
else if (bb != bm) l = update(l, b, m, upd);
else r = update(r, m, e, upd);
T[node].l = l; T[node].r = r;
return node;
}
ll query(int node, int b, int e, int x) {
if (node == -1) return -INF; // <= a * x + b for all lines
int m = (b + e) / 2;
return max(T[node].line.Eval(x), (x <= m
? query(T[node].l, b, m, x)
: query(T[node].r, m + 1, e, x)));
}
void InsertLine(Line l) { root = update(root, -MAX, MAX, l); }
ll EvalMax(int x) { return query(root, -MAX, MAX, 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
ConvexTree 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;
}