Pagini recente » Cod sursa (job #649727) | Cod sursa (job #3287199) | Cod sursa (job #2266593) | Cod sursa (job #3152515) | Cod sursa (job #2737384)
#include <bits/stdc++.h>
// divide pt ca lichao e penal
using namespace std;
struct Line {
int64_t a, b;
Line(int64_t a_, int64_t b_) : a(a_), b(b_) {}
int64_t operator()(const int64_t &x) const { return a * x + b; }
bool operator<(const Line &other) const {
if (a != other.a) return a < other.a;
return b < other.b;
}
};
bool Bad(const Line &x, const Line &y, const Line &z) {
return (__int128_t)(z.b - x.b) * (x.a - y.a) <=
(__int128_t)(y.b - x.b) * (x.a - z.a);
}
void Push(vector<Line> &v, const Line &l) {
while ((int)v.size() >= 2 && Bad(v.end()[-2], v.end()[-1], l))
v.pop_back();
v.emplace_back(l);
}
int main() {
ifstream cin("euro.in");
ofstream cout("euro.out");
int n, t; cin >> n >> t;
vector<int64_t> sum(n);
vector<int64_t> dp(n);
for (int i = 0; i < n; ++i) {
cin >> sum[i];
if (i > 0) sum[i] += sum[i - 1];
dp[i] = sum[i] * (i + 1) - t;
}
auto Divide = [&](int l, int r, auto self) {
if (l == r) {
return vector<Line>{Line(-sum[l], dp[l])};
}
int m = (l + r) / 2;
auto h1 = self(l, m, self);
for (int i = m + 1, ptr = 0; i <= r; ++i) {
while (ptr + 1 < (int)h1.size() && h1[ptr](i + 1) <= h1[ptr + 1](i + 1)) ++ptr;
dp[i] = max(dp[i], h1[ptr](i + 1) + sum[i] * (i + 1) - t);
}
auto h2 = self(m + 1, r, self);
vector<Line> h;
int i = 0, j = 0;
while (i < (int)h1.size() && j < (int)h2.size()) {
if (h1[i] < h2[j]) Push(h, h1[i++]);
else Push(h, h2[j++]);
}
while (i < (int)h1.size()) Push(h, h1[i++]);
while (j < (int)h2.size()) Push(h, h2[j++]);
return h;
};
Divide(0, n - 1, Divide);
cout << dp[n - 1] << endl;
}