Cod sursa(job #137329)

Utilizator bogdan2412Bogdan-Cristian Tataroiu bogdan2412 Data 17 februarie 2008 11:16:18
Problema Stalpi Scor 40
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasa a 10-a Marime 2.18 kb
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

#define MAXN 100005

#define stalp pair< pair<int, int>, pair<int, int> >
#define X first.first
#define Cst first.second
#define L second.first
#define R second.second
#define make_stalp( a, b, c, d ) make_pair( make_pair( (a), (b) ), make_pair( (c), (d) ) )

int N;
vector< stalp > v;
vector<int> coord;

int bst[MAXN];		//bst[i] = costul minim pentru a acoperii primii i stalpi (sortati dupa X)
int aib[MAXN];

inline void aibUpdate( int poz, int val )
{
	poz = N - poz;
	for (; poz < MAXN; poz += poz ^ (poz - 1) & poz)
		if (val < aib[poz])
			aib[poz] = val;
}

inline int aibQuery( int poz )
{
	//N - 1 -> 1
	//N - 2 -> 2
	//...
	//0 -> N
	
	int rez = 0x3f3f3f3f;
	poz = N - poz;
	for (; poz; poz &= (poz - 1))
		if (aib[poz] < rez)
			rez = aib[poz];
	return rez;
}

//returneaza minim( bst[k], k >= poz )
inline int query( int poz )
{
	return aibQuery( poz );

	/*
	int Min = 0x3f3f3f3f;
	for (int i = poz; i < N; i++)
		if (bst[i] < Min)
			Min = bst[i];
	return Min;*/
}

int main()
{
	freopen("stalpi.in", "rt", stdin);
	freopen("stalpi.out", "wt", stdout);

	scanf("%d", &N);
	for (int i = 0; i < N; i++)
	{
		int x, cst, l, r;
		scanf("%d %d %d %d", &x, &cst, &l, &r);

		v.push_back( make_stalp( x, cst, l, r ) );
	}

	memset( aib, 0x3f, sizeof(aib) );
	memset( bst, 0x3f, sizeof(bst) );
	sort( v.begin(), v.end() );
	for (int i = 0; i < N; i++)
		coord.push_back( v[i].X );
	for (int i = 0; i < N; i++)
	{
		int cst = v[i].Cst;

		int left = v[i].X - v[i].L;
		if (left > coord[0])
		{
			int pleft = lower_bound( coord.begin(), coord.end(), left ) - coord.begin();
			if (coord[pleft] < left)		//nush exact cum merge lower_bound cand nu gaseste elementu :P
				pleft++;

			cst += query( pleft );
		}

		int right = v[i].X + v[i].R;
		if (right > coord[N - 1])
			if (cst < bst[N - 1])
			{
				bst[N - 1] = cst;
				aibUpdate( N - 1, cst );
			}
			else;
		else
		{
			int pright = lower_bound( coord.begin(), coord.end(), right ) - coord.begin();
			if (coord[pright] > right)
				pright--;

			if (cst < bst[pright])
			{
				bst[pright] = cst;
				aibUpdate( pright, cst );
			}
		}
	}
	printf("%d\n", bst[N - 1]);
	
	return 0;
}