Cod sursa(job #2742291)

Utilizator armigheGheorghe Liviu Armand armighe Data 20 aprilie 2021 18:35:32
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.94 kb
#include<bits/stdc++.h>
#define INF 1000000000000000
using namespace std;
ifstream f("euro.in");
ofstream g("euro.out");
long long v[34570],s[34570],dp[34570];

struct line
{
    long long a,b;
};
line dq[34570];

long long calc_y(line p,int x)//calculeaza valoare lui y in punctul x pe o dreapta
{
    return p.a*x+p.b;
}

long double calc_x(line p1,line p2)//calculeaza x ul intersectiei celor 2 drepte
{
    //y=a1*x+b1
    //y=a2*x+b2
    //x=(b2-b1)/(a1-a2)
    if(p1.a>p2.a)
        return INF;
    if(p1.a==p2.a)
    {
        if(p1.b>=p2.b)
            return INF;
        return -INF;
    }
    return (long double)(p2.b-p1.b)/(p1.a-p2.a);
}

bool useless(line linie1,line linie2,line linie3)//verifica daca linia 2 e useless(<=> linia 3 o sa se intersecteze cu linia 1 inainte de intersectia lui 1 cu linia 2 si astfel linia 2 nu o sa mai fie minim niciodata)
{
    if(calc_x(linie1,linie2)>=calc_x(linie1,linie3))
        return 1;
    return 0;//if(calc(linie1,linie2)<calc(linie1,linie3)) -> asa e normal
}

int main()
{
    long long n,i,t,st=1,dr=0;
    line linie;
    f>>n>>t;
    for(i=1;i<=n;i++)
        f>>v[i],s[i]=s[i-1]+v[i];
    //panta nu e monotona pe masura ce creste i -> tot putem face deque pe maxime :) , doar ca mai trebuie o conditie in plus
    //merge convex hull trick pt ca i e crescator (sau ce argument e acolo in formula)
    dp[0]=0;
    dq[++dr]={0,0};
    for(i=1;i<=n;i++)
    {
        while(st<dr&&calc_x(dq[st],dq[st+1])<=i)//daca linia 1 nu o sa mai fie maxima cand ajunge la i (pana acolo o sa ii ia locul linia 2)
            st++;
        dp[i]=calc_y(dq[st],i)+s[i]*i-t;
        linie={-s[i],dp[i]};
        while(st<dr&&useless(dq[dr-1],dq[dr],linie)==1)
            dr--;
        dq[++dr]=linie;
       // while(st<dr&&calc_x(dq[dr-1],dq[dr])<=i&&dq[dr-1].a>=dq[dr].a)//daca linia 2 nu e mai buna decat linia 1
       //     dr--;
    }
    g<<dp[n];
    return 0;
}