Cod sursa(job #843501)

Utilizator mihai995mihai995 mihai995 Data 27 decembrie 2012 23:50:07
Problema Euro Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.08 kb
#include <fstream>
#include <iostream>
using namespace std;

const int N = 35001;

struct Smen{
    struct Nod{
        long long a, b;
        int i;

        Nod(){
            i = 0;
        }

        Nod(int _a, int _b, int _i){
            a = _a;
            b = _b;
            i = _i;
        }

        int eval(int t){
            return a * t + b;
        }

        bool surpass(Nod x, Nod y){
            return x.a * b + a * y.b + y.a * x.b >= x.b * a + b * y.a + y.b * x.a;
        }
    };

    Nod v[N];
    int size;

    void push(int a, int b, int i){
        Nod x = Nod(a, b, i);

        while (size > 1 && v[size - 1].surpass(v[size], x))
            size--;

        v[++size] = x;
    }

    void reset(){
        size = 0;
    }

    inline bool okay(int x, int t){
        return v[x].eval(t) > v[x + 1].eval(t);
    }

    int bs(int timp){
        int i, step = 1 << 15;

        for (i = 0 ; step ; step >>= 1)
            if (i + step < size && !okay(i + step, timp))
                i += step;

        return v[i + 1].i;
    }
};

long long S[N], v[N], T;
Smen D;
int n;

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

template<class T>
void print(T v[]){
    for (int i = 1 ; i <= n ; i++)
        cout << v[i] << " ";

    cout << "\n";
}

long long compute(){
    D.reset();

    D.push(n, 0, n + 1);

    for (int i = n ; i ; i--){
        int j = D.bs(S[i]);

        v[i] = v[j] + (j - 1) * (S[i] - S[j]) - T;

        D.push(i - 1, v[i] - S[i] * (i - 1), i);
    }

    //print(v);

    return v[1];
}

long long brute(){
    for (int i = n ; i ; i--){
        v[i] = n * S[i] - T;

        for (int j = i + 1 ; j <= n ; j++)
            v[i] = max(v[i], v[j] + (j - 1) * (S[i] - S[j]) - T);
    }

    print(v);

    return v[1];
}

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

    for (int i = 1 ; i <= n ; i++)
        in >> S[i];

    for (int i = n - 1 ; i ; i--)
        S[i] += S[i + 1];

    //out << brute() << "\n";
    out << compute() << "\n";

    return 0;
}