Pagini recente » Cod sursa (job #2792582) | Cod sursa (job #1660038) | Cod sursa (job #688894) | Cod sursa (job #143295) | Cod sursa (job #2043430)
#include <vector>
#include <iostream>
#include <queue>
#include <set>
#include <cassert>
#include <limits>
#include <algorithm>
#include <map>
using namespace std;
struct Line {
long long a, b;
long long Eval(int x) {
return a * x + b;
}
};
struct ConvexTree {
vector<Line> T;
ConvexTree(int n) : T(4 * n, Line{0, (long long)-1e18}) {}
void Update(int node, int b, int e, Line now) {
Line& cur = T[node];
if (cur.Eval(b) > now.Eval(b) && cur.Eval(e) > now.Eval(e)) return;
if (cur.Eval(b) < now.Eval(b) && cur.Eval(e) < now.Eval(e)) {
cur = now; return;
}
int m = (b + e) / 2;
if (cur.Eval(b) < now.Eval(b)) swap(cur, now);
if (cur.Eval(m) > now.Eval(m))
Update(node * 2 + 1, m + 1, e, now);
else {
swap(cur, now);
Update(node * 2, b, m, now);
}
}
long long EvalMax(int node, int b, int e, int x) {
if (b == e) return T[node].Eval(x);
int m = (b + e) / 2;
long long ans = T[node].Eval(x);
if (x <= m) ans = max(ans, EvalMax(node * 2, b, m, x));
else ans = max(ans, EvalMax(node * 2 + 1, m + 1, e, x));
return ans;
}
};
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(n + 1);
ct.Update(1, 0, n, Line{0, 0});
long long ans = 0, gain = 0;
for (int i = 1; i <= n; ++i) {
int x; cin >> x; gain += x;
ans = ct.EvalMax(1, 0, n, i) + gain * i - t;
ct.Update(1, 0, n, Line{-gain, ans});
}
cout << ans << endl;
return 0;
}