Cod sursa(job #138499)

Utilizator damaDamaschin Mihai dama Data 18 februarie 2008 18:45:16
Problema Stalpi Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.05 kb
#include <stdio.h>
#include <algorithm>

const int nm = 100001;
const long long inf = (long long) 1 << 56;

using namespace std;

struct pula
{
	int x, c, s, d;
};

struct jeg
{
	int st, dr, cost;
};

pula a[nm];
jeg v[nm];
int n;
long long arb[3 * nm];

bool cmp1(pula one, pula two)
{
	return one.x < two.x;
}
bool cmp2(jeg one, jeg two)
{
	return one.dr < two.dr;
}
int bs1(int);
int bs2(int);
long long query(int, int, int, int, int);
void update(int, int, int, int, long long);
void init(int, int, int);
inline long long min(long long a, long long b)
{
	if(a < b)
		return a;
	return b;
}

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

	int i, j;
	long long temp, c[nm];

	scanf("%d", &n);

	for(i = 1; i <= n; ++i)
	{
		scanf("%d %d %d %d", &a[i].x, &a[i].c, &a[i].s, &a[i].d);
	}
	sort(a + 1, a + n + 1, cmp1);

	for(i = 1; i <= n; ++i)
	{
		v[i].st = bs1(a[i].x - a[i].s);
		v[i].dr = bs2(a[i].x + a[i].d);
		v[i].cost = a[i].c;
	//	printf("%d %d %d\n", v[i].st, v[i].dr, v[i].cost);
		c[i] = inf;
	}

	sort(v + 1, v + n + 1, cmp2);

	init(1, 0, n);

	for(i = 1; i <= n; ++i)
	{
		temp = inf;
	//	printf("%d %d ", v[i].st - 1, v[i].dr - 1);
		temp = query(1, 0, n, v[i].st - 1, v[i].dr - 1);
		/*
		for(j = v[i].st - 1; j < v[i].dr; ++j)
		{
			if(temp > c[j])
			{
				temp = c[j];
			}
		}
		*/
	//	printf("%lld\n", temp);
		if(c[v[i].dr] > temp + v[i].cost)
		{
			c[v[i].dr] = temp + v[i].cost;
			//printf("%lld\n", c[v[i].dr]);
			update(1, 0, n, v[i].dr, c[v[i].dr]);
			/*
			for(j = 1; j <= 3 * n; ++j)
			{
				printf("%d %lld\n", j, arb[j]);
			}
			*/
		}
	}

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

	return 0;
}

int bs1(int val)
{
	int min = 1, mid, max = n, rez;

	while(min <= max)
	{
		mid = (min + max) / 2;
		if(a[mid].x >= val)
		{
			rez = mid;
			max = mid - 1;
		}
		else
		{
			min = mid + 1;
		}
	}
	return rez;
}

int bs2(int val)
{
	int min = 1, mid, max = n, rez;

	while(min <= max)
	{
		mid = (min + max) / 2;
		if(a[mid].x <= val)
		{
			rez = mid;
			min = mid + 1;
		}
		else
		{
			max = mid - 1;
		}
	}
	return rez;
}

long long query(int nod, int st, int dr, int a, int b)
{
	int fs = 2 * nod, fd = 2 * nod + 1, mid = (st + dr) / 2;
	long long rez;

	if(st == a && dr == b)
	{
		return arb[nod];
	}
	if(b <= mid)
	{
		return query(fs, st, mid, a, b);
	}
	if(a > mid)
	{
		return query(fd, mid + 1, dr, a, b);
	}
	return min(query(fs, st, mid, a, mid), query(fd, mid + 1, dr, mid + 1, b));
}

void update(int nod, int st, int dr, int pos, long long val)
{
	if(st == dr)
	{
		arb[nod] = val;
	}
	else
	{
		int fs = 2 * nod, fd = 2 * nod + 1, mid = (st + dr) / 2;
		if(pos <= mid)
		{
			update(fs, st, mid, pos, val);
			if(arb[nod] > arb[fs])
				arb[nod] = arb[fs];
		}
		else
		{
			update(fd, mid + 1, dr, pos, val);
			if(arb[nod] > arb[fd])
				arb[nod] = arb[fd];
		}
	}
}

void init(int nod, int st, int dr)
{
	if(st == dr)
	{
		if(st == 0)
		{
			arb[nod] = 0;
		}
		else
		{
			arb[nod] = inf;
		}
	}
	else
	{
		int fs = 2 * nod, fd = 2 * nod + 1, mid = (st + dr) / 2;
		init(fs, st, mid);
		init(fd, mid + 1, dr);
		arb[nod] = arb[fs];
	}
}