Cod sursa(job #2296378)

Utilizator AlexandruLuchianov1Alex Luchianov AlexandruLuchianov1 Data 4 decembrie 2018 17:18:07
Problema Euro Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.82 kb
#include <iostream>
#include <fstream>

using namespace std;

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

#define ll long long
#define MIN(a , b) (((a) < (b)) ? (a) : (b))
#define MAX(a , b) (((a) < (b)) ? (b) : (a))

int const nmax = 34567;
int const inf = 2000000000;

ll dp[5 + nmax];

int sum[5 + nmax];

struct Line{
  ll x;
  ll y;
};

ll eval(Line a , int point){
  return 1LL * point * a.x + a.y;
}

Line aint[5 + 4 * nmax];

void addline(int node , int from , int to , Line line){
  if(from == to){
    if(eval(aint[node] , from) < eval(line , from))
      aint[node] = line;
  } else {
    int mid = (from + to) / 2 + 1;

    bool evalfrom = eval(aint[node] , from) < eval(line , from);
    bool evalmid = eval(aint[node] , mid) < eval(line , mid);
    if(evalfrom == 0 && evalmid == 0)
      addline(node * 2 + 1 , mid , to , line);
    else if(evalfrom == 1 && evalmid == 0)
      addline(node * 2 , from , mid - 1 , line);
    else {
      swap(line , aint[node]);
      if(evalfrom == 0)
        addline(node * 2 , from , mid - 1 , line);
      else
        addline(node * 2 + 1 , mid , to , line);
    }
  }
}

ll query(int node , int from , int to , int x){
  if(from == to)
    return eval(aint[node] , x);
  else{
    int mid = (from + to) / 2 + 1;
    ll result = 0;

    if(x < mid)
      result = query(node * 2 , from , mid - 1 , x);
    else
      result = query(node * 2 + 1 , mid  , to , x);
    return MAX(result , eval(aint[node] , x) );
  }
}

int main()
{
  int n , t;
  in >> n >> t;
  for(int i = 1 ;i <= n ; i++){
    int a;
    in >> a;
    sum[i] = sum[i - 1] + a;
  }

  for(int i = 1 ; i <= n ; i++){
    dp[i] = 1LL * i * sum[i] - t + query(1 , 1 , n , i);
    addline(1 , 1 , n , {-sum[i] , dp[i]});
  }
  out << dp[n];

  return 0;
}