Cod sursa(job #552263)

Utilizator AndreyPAndrei Poenaru AndreyP Data 11 martie 2011 23:07:47
Problema Euro Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.29 kb
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 35010
#define N1 150010
#define ll long long
#define pll pair< ll,ll >
#define fs first
#define sc second
#define mp make_pair

int n,T;
int a[N1];
pll p[N];
int s[N];
int pr,ul,ret;

inline void citire() {
	scanf("%d%d",&n,&T);

	for(int i=1; i<=n; ++i) {
		scanf("%d",&s[i]);
		s[i] += s[i-1];
	}
}

inline ll getVal(int i,int x) {
	return (p[i].fs*(ll)x+p[i].sc);
}

void update(int p,int u,int i) {
	if(p>u)
		return;

	if(pr<=p && u<=ul) {
		a[i] = ret;
		return;
	}

	int m = (p+u)>>1;
	if(pr<=m)
		update(p,m,(i<<1));
	if(m<ul)
		update(m+1,u,((i<<1)+1));
}

void query(int p,int u,int i) {
	if(p>u)
		return;

	if(a[i]>ret)
		ret = a[i];

	if(p==u)
		return;

	int m = (p+u)>>1;

	if(pr<=m)
		query(p,m,(i<<1));
	else
		query(m+1,u,((i<<1)+1));
}

inline void baga(int i) {
	int p=i,u=n,m;
	ll aux,aux1;
	int u1,u2;

	while(p+1<u) {
		m = (p+u)>>1;

		ret = 0;
		pr = m;
		query(1,n,1);
		aux = getVal(ret,m)-getVal(i,m);

		if(aux<0) {
			u = m;
		} else {
			ret = 0;
			pr = m;
			query(1,n,1);
			aux1 = getVal(ret,m+1)-getVal(i,m+1); 

			if(aux==aux1)
				return;
			if(aux>aux1)
				p = m+1;
			else
				u = m-1;
		}
	}

        for(u1=p; u1<=u; ++u1) {
		ret = 0;
		pr = u1;
		query(1,n,1);
		aux = getVal(ret,u1)-getVal(i,u1);

		if(aux<=0LL)
			break;
	}

	ret = 0;
	pr = u1;
	query(1,n,1);
	aux = getVal(ret,u1)-getVal(i,u1);

	if(aux>0LL)
		return;

	p = i,u = n;
	while(p+1<u) {
		m = (p+u)>>1;

		ret = 0;
		pr = m;
		query(1,n,1);
		aux = getVal(ret,m)-getVal(i,m);

		if(aux<0) {
			p = m;
		} else {
			ret = 0;
			pr = m;
			query(1,n,1);
			aux1 = getVal(ret,m+1)-getVal(i,m+1); 

			if(aux==aux1)
				return;
			if(aux>aux1)
				p = m+1;
			else
				u = m-1;
		}
	}

        for(u2=u; u2>=p; --u2) {
		ret = 0;
		pr = u2;
		query(1,n,1);
		aux = getVal(ret,u2)-getVal(i,u2);

		if(aux<=0LL)
			break;
	}

	pr = u1;
	ul = u2;
	ret = i;
	update(1,n,1);
}			

inline void rezolva() {
	for(int i=1; i<=n; ++i) {
		ret = 0;
		pr = i;
		query(1,n,1);

		p[i].fs = (ll)(-s[i]);
		p[i].sc = getVal(ret,i);
		p[i].sc += (ll)s[i]*(ll)i-(ll)T;
		//printf("%d --> %d %lld\n",i,ret,p[i].sc);
		if(i!=n)
			baga(i);
	}
}

int main() {
	freopen("euro.in","r",stdin);
	freopen("euro.out","w",stdout);

	citire();
	rezolva();
	printf("%lld\n",p[n].sc);

	return 0;
}