Cod sursa(job #2758760)

Utilizator Iulia14iulia slanina Iulia14 Data 12 iunie 2021 15:50:58
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.59 kb
#include <iostream>

using namespace std;
#define ll long long
const int N = 1e5 + 5;
ll dp[N];
struct line{
    ll a, b;
} seg[4 * N];
void update(ll nod, ll l, ll r, ll a, ll b)
{
    if (l == r)
    {
        if (seg[nod].a * l + seg[nod].b < a * l + b)
            seg[nod] = {a, b};
        return;
    }
    ll mid = (l + r) / 2, ls = 2 * nod, rs = ls + 1;
    bool ok_rgt = seg[nod].a * r + seg[nod].b < a * r + b;
    bool ok_mid = seg[nod].a * mid + seg[nod].b < a * mid + b;
    if (!ok_mid && !ok_rgt)
        update(ls, l, mid, a, b);
    else
    if (!ok_mid && ok_rgt)
        update(rs, mid + 1, r, a, b);
    else
    {
        swap(seg[nod].a, a);
        swap(seg[nod].b, b);
        if (ok_rgt)
            update(ls, l, mid, a, b);
        else
            update(rs, mid + 1, r, a, b);
    }
}
ll query (ll nod, ll l, ll r, ll x){
    if (l == r)
        return seg[nod].a * x + seg[nod].b;
    ll mid = (l + r) / 2, ls = 2 * nod, rs = ls + 1, ans = seg[nod].a * x + seg[nod].b;
    if (x <= mid)
        ans = max(ans, query(ls, l, mid, x));
    else
        ans = max(ans, query(rs, mid + 1, r, x));
    return ans;
}
int main()
{
    freopen("euro.in", "r", stdin);
    freopen("euro.out", "w", stdout);
    ///dp[i] = i * sp[i] - t + max(-sp[j] * i + dp[j])
    ll n, t, i, sp = 0;
    cin >> n >> t;
    update(1, 1, n, 0, 0);
    for (i = 1; i <= n; i++)
    {
        ll x;
        cin >> x;
        sp += x;
        dp[i] = i * sp - t + query(1, 1, n, i);
        update(1, 1, n, -sp, dp[i]);
    }
    cout << dp[n];
    return 0;
}