Cod sursa(job #23465)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 28 februarie 2007 19:55:21
Problema Euro Scor 35
Compilator c Status done
Runda Arhiva de probleme Marime 1.37 kb
/*
 * O(N) solution
 * Reference: batch IOI 2002
 */

#include <stdio.h>

#define MAXN 34569

int N, Nin, T;
int x[MAXN], init[MAXN], d[MAXN], s[MAXN];
long long best[MAXN];

inline double g(int b, int a)
{
	return ((double)best[a - 1] - best[b - 1]) / ((double)s[a + 1] - s[b - 1]);
}

int d[MAXN], dl, dr;

int main()
{
	freopen("euro.in", "rt", stdin);
	freopen("euro.out", "wt", stdout);
	scanf("%d %d", &Nin, &T);
	int i, S = 0;
	s[ N = 0 ] = 0;
	for (i = 1; i <= Nin; i++)
	{
		scanf("%d", init + i);
		S += init[i];			//atata timp cat am in cont o valoare pozitiva nu voi obtine profitul maxim daca fac conversie
		if (S < 0)			//abia atunci cand obtin in cont o valoare negativa trebuie sa iau in considerare conversia
		{				//=> comprim intervalele cu valori pozitive
			x[ ++N ] = S;
			s[ N ] = s[ N - 1 ] + S;
			d[ N ] = i;
			S = 0;
		}
	}
	if (d[ N ] != Nin)
	{
		x[ ++N ] = S;
		s[ N ] = s[ N - 1 ] + S;
		d[ N ] = Nin;
	}

	best[0] = 0;
	best[1] = d[1] * s[1] - T;
	d[dl = dr = 0] = 1;
	
	for (i = 2; i <= N; i++)
	{
		while (dl < dr && g( d[dl], d[dl + 1] ) <= d[i])
			dl++;

		best[i] = d[i] * s[i] - T;	//toata secventa 0..i
		long long aux = best[ d[dl] ] + d[i] * (s[i] - s[ d[dl] ]) - T;
		if (aux > best[i])
			best[i] = aux;		//secventa d[dl]..i

		while (dl < dr && g( d[dr - 1], d[dr] ) >= g( d[dr], i ))
			dr--;
		d[++dr] = i;
	}
	
	printf("%lld\n", best[N]);
	return 0;
}