Cod sursa(job #3137074)

Utilizator RolandPetreanPetrean Roland RolandPetrean Data 11 iunie 2023 10:10:27
Problema Euro Scor 50
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.5 kb
// https://infoarena.ro/problema/euro
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'

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

#define int long long
const int INF=-1e18;

struct Line {
  int a, b;
  Line(int a_i, int b_i) {a=a_i, b=b_i;}

  int operator()(int x) {
    return a*x+b;
  }
};
struct Node {
  int st, dr;
  Line f=Line(0,INF);
  Node *left=nullptr, *right=nullptr;

  Node(int st_i, int dr_i) {st=st_i, dr=dr_i;}
  void extend() {
    if (!left && st < dr) {
      int mid=(st+dr)/2;
      left = new Node(st, mid);
      right = new Node(mid+1, dr);
    }
  }

  void add_line(Line l) {
    int mid=(st+dr)/2;
    bool smaller_left = (l(st) > f(st));
    bool smaller_mid = (l(mid) > f(mid));
    
    if (smaller_mid) swap(l, f);
    if (st>=dr) return;

    extend();
    if (smaller_left != smaller_mid) left->add_line(l);
    else right->add_line(l);
  }
  int get_y(int x) {
    if (st==dr) return f(x);
    int mid=(st+dr)/2, res=f(x);
    if (x<=mid && left) res = max(res, left->get_y(x));
    else if (right) res = max(res, right->get_y(x));
    return res;
  }
};

const int MAXN=35000;
int a[MAXN], dp[MAXN];

signed main() {
  int n, t;
  fin>>n>>t;

  for (int i=1; i<=n; ++i) fin>>a[i];
  for (int i=n; i>=1; --i) a[i] += a[i+1];

  Node lichao = Node(-1000, 1000);

  // dp[i] = (a[i] * j - a[j+1]*j + dp[j+1]) - t
  for (int i=n; i>=1; --i) {
    dp[i] = max(dp[i+1] + (a[i]-a[i+1])*i, lichao.get_y(a[i])) - t;
    lichao.add_line(Line(i, dp[i+1] - i*a[i+1]));
  }

  fout<<dp[1];
}