Cod sursa(job #23181)

Utilizator gcosminGheorghe Cosmin gcosmin Data 28 februarie 2007 13:36:22
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <stdio.h>

#define LL long long
#define NMAX 35000

int N, T;

int a[NMAX];
int b[NMAX];
int sp[NMAX];
int t[NMAX];

int p, q;
int deck[NMAX];

LL din[NMAX];

LL LMAX(LL a, LL b) { return (a > b) ? a : b; }

void solve_jeg() //:)
{
    int last = 1, lc, i, j, s;
    LL aux;
    for (i = 1; i <= b[0]; i++) {
        din[i] = -((LL)1 << 62);
        if (i == b[0]) last = 1;
        for (j = i, s = 0; j >= last; j--) {
            s += b[j];
            aux = din[j-1] + (LL) s * t[i] - T;
            if (aux > din[i]) din[i] = aux, lc = j;
 		}   	
 		last = lc;
    }
    
    printf("%lld\n", din[b[0]]);
}    

int main()
{
	int i, j, s;
    
    freopen("euro.in", "r", stdin);
    freopen("euro.out", "w", stdout);
    
    scanf("%d %d", &N, &T);
    
    for (i = 1; i <= N; i++) scanf("%d", &a[i]);
    
    for (i = 1; i <= N; ) {
        for (s = 0, j = i; j <= N && s >= 0; s += a[j], j++);
        
        b[++b[0]] = s;
        t[++t[0]] = j - 1;
        
        i = j;   	
    }
    
	// smecheria cu deque in O(n) :) // sa vedem daca merge
	
	for (i = 1; i <= b[0]; i++) sp[i] = sp[i-1] + b[i];
	
	p = 0;
	q = -1;
	
	din[b[0]] = (LL) sp[b[0]] * t[b[0]] - T;
	
	for (i = 1; i < b[0]; i++) {
	    din[i] = -((LL)1 << 62);
	    
	    // scot din varful cozii
	    while (p < q && din[deck[p+1]] - din[deck[p]] > (LL) t[i] * (sp[deck[p+1]] - sp[deck[p]])) p++;
	    
	    // aflu pentru curent
	    din[i] = LMAX( (LL) sp[i] * t[i] - T, (p <= q) ? (LL) (sp[i] - sp[deck[p]]) * t[i] - T + din[deck[p]] : -((LL) 1 << 62));
	    
	    din[b[0]] = LMAX(din[b[0]], din[i] + (LL) (sp[b[0]] - sp[i]) * t[b[0]] - T);
	    
	    // bag curentul in coada
	    while (p < q && (long double) (din[i] - din[deck[q]]) / (sp[i] - sp[deck[q]]) <= (long double) (din[deck[q]] - din[deck[q-1]]) / (sp[deck[q]] - sp[deck[q-1]])) q--;
	    deck[++q] = i;
	}    
	
	printf("%lld\n", din[b[0]]);
	
fclose(stdin);
fclose(stdout);
return 0;
}