Cod sursa(job #137612)

Utilizator victorsbVictor Rusu victorsb Data 17 februarie 2008 12:47:54
Problema Stalpi Scor 100
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasa a 10-a Marime 2.11 kb
#include <cstdio>
#include <algorithm>

using namespace std;

#define Nmax 100015
#define Amax 262144
#define pii pair<int,int>
#define mp make_pair
#define x first.second
#define y first.first
#define cost second
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3fLL

int n;
int sir[Nmax];
int c[Nmax], s[Nmax], d[Nmax];
pair<pii, int> p[Nmax];
ll D[Nmax];
ll ai[Amax];
ll Q;

void citire()
{
	int i;

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

void cauta(int i)
{
	int st, dr, mij;

	p[i] = mp(mp(0, n + 1), c[i]);

	st = 1;
	dr = n;
	while (st <= dr)
	{
		mij = (st + dr) / 2;
		if (sir[mij] >= s[i])
		{
			p[i].x = mij;
			dr = mij - 1;
		}
		else
			st = mij + 1;
	}

	st = 1;
	dr = n;
	while (st <= dr)
	{
		mij = (st + dr) / 2;
		if (sir[mij] <= d[i])
		{
			p[i].y = mij;
			st = mij + 1;
		}
		else
			dr = mij - 1;
	}

	if (p[i].x == 1 && p[i].y == 20 && p[i].cost == 1)
		printf("%d\n", i);
}

void update(int nod, int st, int dr, int a)
{
	if (st == dr)
	{
		ai[nod] = D[a];
	}
	else
	{
		int mij = (st + dr) / 2, fs = nod * 2, fd = nod * 2 + 1;

		if (a <= mij) update(fs, st, mij, a);
		else update(fd, mij + 1, dr, a);

		ai[nod] = min(ai[fs], ai[fd]);
	}
}

void query(int nod, int st, int dr, int a, int b)
{
	if (a <= st && dr <= b)
	{
		Q = min(Q, ai[nod]);
	}
	else
	{
		int mij = (st + dr) / 2, fs = nod * 2, fd = nod * 2 + 1;

		if (a <= mij) query(fs, st, mij, a, b);
		if (mij < b) query(fd, mij + 1, dr, a, b);
	}
}

void solve()
{
	int i;

	sort(sir+1, sir+n+1);
    for (i = 1; i <= n; ++i)
		cauta(i);
	sort(p+1, p+n+1);

	memset(D, 0x3f, sizeof(D));
	D[0] = 0;
	memset(ai, 0x3f, sizeof(ai));
	for (i = 1; i <= n; ++i)
	{
		if (p[i].x == 1)
		{
			D[p[i].y] = min(D[p[i].y], (ll)p[i].cost);
			update(1, 1, n, p[i].y);
		}
		else
		{
			Q = INF;
			query(1, 1, n, p[i].x - 1, p[i].y - 1);
			D[p[i].y] = min(D[p[i].y], Q + p[i].cost);
			update(1, 1, n, p[i].y);
		}
	}

	printf("%lld\n", D[n]);
}

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

	citire();
	solve();

	return 0;
}