Cod sursa(job #1980518)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 13 mai 2017 11:56:08
Problema Euro Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.2 kb
#include <bits/stdc++.h>

using namespace std;

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

typedef long long ll;
const ll inf = 2e9;
int n, T, i, sum, x; ll dp;

struct line
{
    int A; ll B;
    mutable long double slope;

    ll get_valeur(int x) const
    {
        return 1LL * A * x + B;
    }

    line(int _A, ll _B, ll _slope = 0)
    {
        A = _A; B = _B; slope = _slope;
    }

    bool operator < (const line &other) const
    {
        if(other.A == inf) return slope < other.slope;
        if(A == other.A) return B < other.B;
        return A < other.A;
    }
};

class Batch : public set<line>
{
    void refresh(iterator it)
    {
        auto nxt =  next(it);
        if(nxt == end()) it->slope = (long double) inf * inf;
            else it->slope = (long double) (it->B - nxt->B) / (nxt->A - it->A);
    }

    bool bad(iterator it)
    {
        auto nxt = next(it);
        if(nxt == end()) return 0;
        if(it == begin()) return 0;
        auto prv = prev(it);

        return (long double) (prv->B - nxt->B) * (nxt->A - it->A) >= (long double) (it->B - nxt->B) * (nxt->A - prv->A);
    }

    public:
        ll query(int x)
        {
            return lower_bound(line(inf, 0, x)) -> get_valeur(x);
        }

        void add(line Line)
        {
            auto itt = insert(Line);
            if(!itt.second) return;
            auto it = itt.first;

            if(next(it)!=end() && next(it)->A == it->A)
            {
                erase(it);
                return;
            }

            if(it!=begin() && prev(it)->A == it->A)
                erase(prev(it));

            if(bad(it))
            {
                erase(it);
                return;
            }

            while(it!=begin() && bad(prev(it)))
                erase(prev(it));

            while(next(it)!=end() && bad(next(it)))
                erase(next(it));

            refresh(it);
            if(it!=begin()) refresh(prev(it));
        }
} batch;

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

    sum = 0; batch.add(line(0, 0));
    for(i=1; i<=n; ++i)
    {
        fin >> x; sum += x;

        dp = batch.query(i) + 1LL * sum * i - T;
        batch.add(line(-sum, dp));
    }

    fout << dp << '\n';

    return 0;
}