Cod sursa(job #2735643)

Utilizator MateiAruxandeiMateiStefan MateiAruxandei Data 2 aprilie 2021 17:23:50
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Lista lui wefgef Marime 1.94 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin("euro.in");
ofstream fout("euro.out");

const int NMAX(34580);
const long long inf(LLONG_MIN);
typedef long long ll;
ll dp[NMAX], v[NMAX], sum[NMAX], AIB[NMAX], AIB2[NMAX];
int n, t;

struct ecuatie
{
    ll a, b;
    ll Calc(ll x)
    {
        return a * x + b;
    }
};

struct Node
{
    ecuatie ec;
    int st = -1, dr = -1;
};

class Arb
{
public:
    vector<Node> copac;
    int rad = -1;

    int Update(int nod, int st, int dr, ecuatie &nou)
    {
        if(nod == -1)
        {
            Node aux;
            aux.ec = nou;
            copac.push_back(aux);
            return copac.size() - 1;
        }

        ecuatie & cur = copac[nod].ec;
        int mij = (st + dr) / 2;
        int s = copac[nod].st;
        int d = copac[nod].dr;
        bool ss = (nou.Calc(st) > cur.Calc(st));
        bool mm = (nou.Calc(mij) > cur.Calc(mij));
        if(mm)
            swap(cur, nou);
        if(dr - st == 1);
        else if(ss != mm)
            s = Update(s, st, mij, nou);
        else d = Update(d, mij, dr, nou);
        copac[nod].st = s;
        copac[nod].dr = d;
        return nod;
    }

    ll Query(int nod, int st, int dr, int x)
    {
        if(nod == -1)
            return -1e9;
        int mij = (st + dr) / 2;
        return max(copac[nod].ec.Calc(x), (x <= mij ? Query(copac[nod].st, st, mij, x): Query(copac[nod].dr, mij + 1, dr, x)));
    }

    void Ins(ecuatie ec){
        rad = Update(rad, -1e9, 1e9, ec);
    }
    ll EvalMax(int x){
        return Query(rad, -1e9, 1e9, x);
    }
};

int main()
{
    fin >> n >> t;

    Arb Arbore;
    Arbore.Ins({0, 0});

    for(int i = 1; i <= n; ++i)
    {
        fin >> v[i];
        sum[i] = sum[i - 1] + v[i];
        dp[i] = Arbore.EvalMax(i) + sum[i] * i - t;
        Arbore.Ins({-sum[i], dp[i]});
    }

    fout << dp[n] << '\n';
    return 0;
}