Cod sursa(job #278765)

Utilizator pauldbPaul-Dan Baltescu pauldb Data 12 martie 2009 15:16:01
Problema Stalpi Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <fstream>
#include <algorithm>

using namespace std;

#define MAXN 100010
#define MAXX 262144
#define ll long long
#define INF 1000000000000LL

int N, L;
int ileft, iright;
ll value;
int X[MAXN], S[MAXN], D[MAXN], Cost[MAXN];
int Q[MAXN], P[MAXN];
ll C[MAXN], best[MAXX];

int cmp(int i, int j)
{
	return X[i] + D[i] < X[j] + D[j];
}

int cmp2(int i, int j)
{
	return X[i] < X[j];
}

int search(int x)
{
	int front = 1, middle, back = N, rez = 0;

	while (front <= back)
	{
		middle = (front + back) / 2;

		if (X[Q[middle]] < x)
		{
			rez = middle;
			front = middle + 1;
		}
		else back = middle - 1;
	}

	return rez;
}

int search2(int x)
{
	int front = 1, middle, back = N, rez = 0;

	while (front <= back)
	{
		middle = (front + back) / 2;
		
		if (X[P[middle]] + D[P[middle]] >= x)
		{
			rez = middle;
			back = middle - 1;
		}
		else front = middle + 1;
	}

	return rez;
}

ll query(int p, int r, int nod)
{
	if (ileft <= p && r <= iright) return best[nod];
	else {
			 int q = (p+r) / 2;
			 ll rez = INF;
 
			 if (ileft <= q) rez = query(p, q, nod*2);
			 if (q < iright) rez = min(rez, query(q+1, r, nod*2+1));

			 return rez;
		 }
}

void update(int p, int r, int nod)
{
	if (p == r) best[nod] = value;
	else {
			 int q = (p+r) / 2;

			 if (ileft <= q) update(p, q, nod*2);
			 if (q < iright) update(q+1, r, nod*2+1);

			 best[nod] = min(best[nod*2], best[nod*2+1]);
		 }
}

int main()
{
	ifstream fin("stalpi.in");
	ofstream fout("stalpi.out");

	int i;

	fin >> N;

	for (i = 1; i <= N; i++)
	{
		fin >> X[i] >> Cost[i] >> S[i] >> D[i];
		P[i] = Q[i] = i;
	}

	for (L = 1; L < N; L <<= 1);
	for (i = 1; i < 2*L; i++) best[i] = INF;

	sort(P+1, P+N+1, cmp);
	sort(Q+1, Q+N+1, cmp2);

	for (i = 1; i <= N; i++)
	{
		ileft = search(X[P[i]] - S[P[i]]);	

		if (ileft == 0) C[i] = Cost[P[i]];
		else {
				 ileft = search2(X[Q[ileft]]);
				 iright = i-1;

		 		 if (ileft > iright) C[i] = INF;
			 	 else C[i] = query(1, L, 1) + Cost[P[i]];
			 }

		ileft = iright = i;
		value = C[i];
		update(1, L, 1);
	}

	ileft = search2(X[Q[N]]);
	iright = N;

	fout << query(1, L, 1) << endl;

	return 0;
}