Cod sursa(job #23372)

Utilizator wefgefAndrei Grigorean wefgef Data 28 februarie 2007 18:40:16
Problema Euro Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.37 kb
#include <cstdio>
#include <algorithm>
#include <vector>

using namespace std;

#define pb push_back
#define sz size()
#define mp make_pair
#define x first
#define y second

#define Nmax 34568

int n;
long long t;
vector< pair<long long, int> > v;
int Q[Nmax], qb, qe;
long long best[Nmax], sum[Nmax];

void readdata()
{
	freopen("euro.in", "r", stdin);
	freopen("euro.out", "w", stdout);
	
	long long sum = 0, val;
	int i;
	
	scanf("%d %lld", &n, &t);
	for (i = 1; i <= n; ++i)
	{
		scanf("%lld", &val);
		sum += val;
		if (sum < 0)
		{
			v.pb( mp(sum, i) );
			sum = 0;
		}
	}
	if (v.sz == 0 || v[v.sz-1].y < n) v.pb( mp(sum, n) );
	
	for (i = v.sz-1; i; --i)
		v[i].y = v[i-1].y;
	v[i].y = 0;
}

long double g(int a, int b)
{
	return (long double)(best[a] - best[b]) / (long double)(v[b].y - v[a].y);
}

void solve()
{
	int i, nr = v.sz-1;
	
	for (i = nr; i >= 0; --i)
		sum[i] = sum[i+1]+v[i].x;
	
	best[nr] = (n-v[nr].y)*sum[nr] - t;	
	
	Q[qb = qe = 1] = nr;
	for (i = nr-1; i >= 0; --i)
	{
		best[i] = best[ Q[qb] ] + (v[Q[qb]].y - v[i].y)*sum[i] - t;
		best[i] = max(best[i], (n-v[i].y)*sum[i]-t);		
		while (qe > qb && g(Q[qb+1], Q[qb]) >= sum[i]) ++qb;

		while (qe > qb && g(i, Q[qe]) <= g(Q[qe], Q[qe-1])) --qe;
		Q[++qe] = i;
	}
	printf("%lld\n", best[0]);
}

int main()
{
	readdata();
	solve();
	return 0;
}