Cod sursa(job #2290876)

Utilizator giotoPopescu Ioan gioto Data 27 noiembrie 2018 09:37:03
Problema Euro Scor 35
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <bits/stdc++.h>
using namespace std;

typedef complex<long long> point;
#define x real
#define y imag
const int MAX = 1e3;


struct nod{
    point line;
    nod *left, *right;
    nod(){
        line = {MAX, MAX};
        left = right = NULL;
    }
};
typedef nod * node;

int n, t;

///Li Chao
long long dot(point a, point b){
    return (conj(a) * b).x();
}
long long f(point line, int x){
    return dot({x, 1}, line);
}

node arb;
void add_line(point line, node &Nod = arb, int st = 1, int dr = n){
    int mij = (st + dr) / 2;

    bool lef = f(line, st) < f(Nod->line, st);
    bool mid = f(line, mij) < f(Nod->line, mij);

    if(mid) swap(line, Nod->line);

    if(st == dr) return ;

    if(lef != mid){
        if(Nod->left == NULL){
            Nod->left = new nod;
            Nod->left->line = line;
        }
        else add_line(line, Nod->left, st, mij);
    }
    else{
        if(Nod->right== NULL){
            Nod->right = new nod;
            Nod->right->line = line;
        }
        else add_line(line, Nod->right, mij + 1, dr);
    }
}

long long query(int x, node nod = arb, int st = 1, int dr = n){
    int mij = (st + dr) / 2;

    long long val = f(nod->line, x);
    if(st == dr) return val;
    if(nod->left != NULL) val = min(query(x, nod->left, st, mij), val);
    if(nod->right != NULL) val = min(query(x, nod->right, mij + 1, dr), val);

    return val;
}

int main()
{
    freopen("euro.in", "r", stdin);
    freopen("euro.out", "w", stdout);

    scanf("%d%d", &n, &t);
    int s = 0, x;

    arb = new nod;
    arb->line = {0, 0};
    for(int i = 1; i <= n ; ++i){
        scanf("%d", &x);
        s += x;

        long long q = -query(i);
        long long dp = q + 1LL * s * i - t;
        point nl = {s, -dp};
        add_line(nl);

        if(i == n) printf("%lld", dp);
    }
    return 0;
}