Cod sursa(job #137187)

Utilizator mugurelionutMugurel-Ionut Andreica mugurelionut Data 17 februarie 2008 09:52:14
Problema Stalpi Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasa a 10-a Marime 1.87 kb
#include <stdio.h>

#include <vector>
#include <algorithm>
using namespace std;

#define BIGINT long long //__int64 // long long
#define fmt "%lld" //"%I64d" // "%lld"
#define INF 1000000000000

#define NMAX 100100

vector<int> xv;
vector<pair<int, pair<int, int> > > intv;
BIGINT dqv[NMAX], newv;
int dqx[NMAX], left, right;
int i, j, k, X, C, S, D, N, ridx, lidx, dqlidx, lx, rx, li, ls, mid;

int main()
{
	freopen("stalpi.in", "r", stdin);

	scanf("%d", &N);

	for (i = 1; i <= N; i++)
	{
		scanf("%d %d %d %d", &X, &C, &S, &D);
		xv.push_back(X);
		intv.push_back(make_pair(X + D, make_pair(X - S, C)));
	}

	sort(xv.begin(), xv.end());
	sort(intv.begin(), intv.end());

	dqx[left = right = 1] = 0;
	dqv[right] = 0;

	// DP

	ridx = 0;

	for (i = 0; i < N; i++)
	{
		rx = intv[i].first;
		lx = intv[i].second.first;
		C = intv[i].second.second;

		while (ridx < N && rx >= xv[ridx])
			ridx++;

		// find lidx (binary search)
		li = 0; ls = ridx - 1;
		lidx = -1;
		
		while (li <= ls)
		{
			mid = (li + ls) >> 1;

			if (xv[mid] >= lx)
				lidx = mid,
				ls = mid - 1;
			else
				li = mid + 1;
		}

		if (lidx >= 0) // this should always be true
		{
			// binary search inside the dqeue

			li = left; ls = right;
			dqlidx = left - 1;
		
			while (li <= ls)
			{
				mid = (li + ls) >> 1;

				if (dqx[mid] >= lidx)
					dqlidx = mid,
					ls = mid - 1;
				else
					li = mid + 1;
			}

			if (dqlidx >= left)
			{		
				newv = dqv[dqlidx] + (BIGINT) C;
				
				// insert into the deque

				while (left <= right && dqv[right] >= newv)
					right--;

				right++;
				dqv[right] = newv;
				dqx[right] = ridx;
			}
		}
	}

	freopen("stalpi.out", "w", stdout);

	newv = INF;

	for (i = left; i <= right; i++)
		if (dqx[i] == N && dqv[i] < newv)
			newv = dqv[i];

	printf(fmt, newv);

	return 0;
}