Cod sursa(job #1980479)

Utilizator Alexa2001Alexa Tudose Alexa2001 Data 13 mai 2017 11:00:57
Problema Euro Scor 85
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.93 kb
#include <bits/stdc++.h>

using namespace std;

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

typedef long long ll;
int n, T, i, sum, x; ll dp;

struct line
{
    int A; ll B;

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

    line(int _A, int _B)
    {
        A = _A; B = _B;
    }

    friend bool operator < (const line &one, const line &two)
    {
        if(one.A == two.A) return one.B < two.B;
        return one.A < two.A;
    }
};

long double intersect(line one, line two)
{
    return (long double) (one.B - two.B) / (two.A - one.A);
}

class Batch : public set<line>
{
    bool bad(iterator it)
    {
        auto nxt = next(it);
        if(nxt == end()) return 0;
        if(it == begin()) return 0;
        auto prv = prev(it);

        return intersect(*prv, *nxt) >= intersect(*it, *nxt);
    }

    public:
        ll query(int x)
        {
            while(size()>=2 && intersect(*begin(), *next(begin())) <= x)
                erase(begin());
            return begin() -> 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));
        }
} 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;
}