Cod sursa(job #2640084)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 5 august 2020 00:07:03
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.65 kb
/*
 *  Created by Andrei Arhire 01/08/2020
 *  Copyright © 2020 Andrei Arhire. All rights reserved.
 */
#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define lll long long
#define llf __float128
#define lld long double
using namespace std;
const lll NR = 1e5 + 10  ,oo = 2e9 + 10, MOD = 1e9 + 7 ;
const long double pi = 2*acos(0.0);

struct cht{
    struct Line{
        lll a;
        long long b;
        long long val;
        double xLeft;
        bool type;
        Line(long long _a = 0 , long long _b = 0){
            a = _a;
            b = _b;
            xLeft = -1e16;
            type = 0;
            val = 0;
        }
        long long valueAt(lll x) const{
            return 1LL * a * x + b;
        }
        friend bool areParallel(const Line &l1, const Line &l2){
            return l1.a == l2.a;
        }
        friend double lllersectX(const Line &l1 , const Line &l2){
            return areParallel(l1 , l2) ? 1e16 : 1.0 * (l2.b - l1.b) / (l1.a - l2.a);
        }
        bool operator < (const Line &l2) const{
            if(!l2.type)
                return a < l2.a;
            return xLeft > l2.val;
        }
    };
    set < Line >  hull;
    bool hasPrev(set < Line > :: iterator it){
        return it != hull.begin();
    }
    bool hasNext(set < Line > :: iterator it){
        return it != hull.end() && next(it) != hull.end();
    }
    bool irrelevant(const Line &l1 , const Line &l2 , const Line &l3){
        return lllersectX(l1,l3) <= lllersectX(l1,l2);
    }
    bool irrelevant(set < Line > :: iterator it){
        return hasPrev(it) && hasNext(it) && (irrelevant(*next(it) , *it , *prev(it)));
    }
    set < Line > :: iterator updateLeftBorder(set < Line > :: iterator it){
        if(!hasNext(it)){
            return it;
        }
        double val = lllersectX(*it , *next(it));
        Line buf(*it);
        it = hull.erase(it);
        buf.xLeft = val;
        it = hull.insert(it, buf);
        return it;
    }
    void addLine(lll a , lll b){
        Line l3 = Line(a, b);
        auto it = hull.lower_bound(l3);
        if(it != hull.end() && areParallel(*it , l3)){
            if(it -> b > b){
                it = hull.erase(it);
            }
            else{
                return;
            }
        }
        it = hull.insert(it, l3);
        if(irrelevant(it)){
            hull.erase(it);
            return;
        }
        while(hasPrev(it) && irrelevant(prev(it))){
            hull.erase(prev(it));
        }
        while(hasNext(it) && irrelevant(next(it))){
            hull.erase(next(it));
        }
        it = updateLeftBorder(it);
        if(hasPrev(it)){
            updateLeftBorder(prev(it));
        }
        if(hasNext(it)){
            updateLeftBorder(next(it));
        }
    }
    long long getBest(lll x){
        Line q;
        q.val = x;
        q.type = 1;
        auto bestLine = hull.lower_bound(q);
        if(bestLine == hull.end()){
            return 1e16;
        }
        return bestLine -> valueAt(x);
    }
};

lll sp [ NR ] , n , t , dp [ NR ] ;
ifstream in ("euro.in") ;
ofstream out ("euro.out") ;
signed main () {
    cht mycht ;
    lll i , x , y ;
    ios::sync_with_stdio(0);
    in.tie(0);
    out.tie(0) ;

    in >> n >> t ;
    mycht.addLine( 0 , 0 ) ;
    for ( i = 1 ; i <= n ; ++ i )   {
        in >> x ;
        sp [ i ] = x + sp [ i - 1 ] ;
        dp [ i ] = ( i * sp [ i ] - t ) * (-1) + mycht.getBest( i ) ;
        mycht.addLine( sp [ i ] , dp [ i ] ) ;
    }
    out << - dp [ n ] << '\n' ;
    return 0 ;
}