Cod sursa(job #2223759)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 21 iulie 2018 14:32:17
Problema Euro Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.57 kb
#include <bits/stdc++.h>
using namespace std;

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

using i64 = long long;

const int N = 40005;

class LiChao {
	struct Line {
		i64 a, b;
		inline i64 operator [] (const i64 &x) const {
			return a * x + b; } };

	vector<Line> pom;
	int qx;

public:
	int n;
	LiChao(int _n) : n(_n), pom(4 * _n, {0, i64(-1e18)}) { }


	void update(int nod, int st, int dr, Line now) {
		if (st == dr) {
			pom[nod] = pom[nod][st] <= now[st] ? now : pom[nod];
			return; }
		if (pom[nod][st] >= now[st] && pom[nod][dr] >= now[dr])
			return;
		if (pom[nod][st] < now[st] && pom[nod][dr] < now[dr]) {
			pom[nod] = now;
			return; }

		int mid = (st + dr) / 2;

		if (pom[nod][st] > now[st])
			swap(now, pom[nod]);
		if (pom[nod][mid] < now[mid])
			update(2 * nod, st, mid, now);
		else {
			swap(now, pom[nod]);
			update(2 * nod + 1, mid + 1, dr, now); } }

	void update(i64 a, i64 b) {
		update(1, 1, n, {a, b}); }

	i64 query(int nod, int st, int dr) {
		if (st == dr) return pom[nod][st];
		i64 ans(pom[nod][qx]);
		int mid((st + dr) / 2);

		ans = qx <= mid ? max(ans, query(2 * nod, st, mid)) : max(ans, query(2 * nod + 1, mid + 1, dr));
		return ans; }

	i64 query(int _qx) {
		qx = _qx;
		return query(1, 1, n); } };

i64 s[N], dp[N];


LiChao *batch;
int n, comision;


int main() {
	fi >> n >> comision;
	for (int i = 1; i <= n; ++i) {
		fi >> s[i];
		s[i]+= s[i - 1]; }

	batch = new LiChao(n);
	batch->update(0, 0);
	for (int i = 1; i <= n; ++i) {
		dp[i] = s[i] * i + batch->query(i) - comision;
		batch->update(-s[i], dp[i]); }

	fo << dp[n] << endl;

	return 0; }