Cod sursa(job #137686)

Utilizator sims_glAlexandru Simion sims_gl Data 17 februarie 2008 12:55:50
Problema Stalpi Scor 0
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasele 11-12 Marime 1.9 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

#define nm 100100
#define mm 400100

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

int n, m;
long long c[mm];
stalp a[nm];

inline long long min(long long a, long long b)
{
	if (a < b)
		return a;
	return b;
}

inline int max(int a, int b)
{
	if (a > b)
		return a;
	return b;
}

long long query(int nod, int x, int y, int st, int dr)
{
	if (x == st && y == dr)
		return c[nod];

	if (st > (x + y) / 2)
		return query(nod * 2 + 1, (x + y) / 2 + 1, y, st, dr);
		
	if (dr <= (x + y) / 2)
		return query(nod * 2, x, (x + y) / 2, st, dr);

	return min(query(nod * 2, x, (x + y) / 2, st, (x + y) / 2), query(nod * 2 + 1, (x + y) / 2 + 1, y, (x + y) / 2 + 1, dr));
}

void update(int nod, long long val)
{
	while (nod > 1) {
		nod -= val;
		nod /= 2;
	}
}

int comp(stalp a, stalp b)
{
	return a.x < b.x;
}

int comp2(stalp a, stalp b)
{
	return a.d < b.d;
}

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

	scanf("%d", &n);
	
	for (m = 1; m < n; m <<= 1);
	m = 2 * n - 1;
	
	for (int 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, comp);

	for (int i = 1; i <= n; ++i) {
		int crt, step;

		for (step = 1; step < n; step <<= 1);

		for (crt = n; step; step >>= 1)
			if (crt > step && a[crt - step].x >= a[i].x - a[i].s)
				crt -= step;

		a[i].s = crt;

		for (step = 1; step < n; step <<= 1);

		for (crt = 0; step; step >>= 1)
			if (crt + step <= n && a[crt + step].x <= a[i].x + a[i].d)
				crt += step;

		a[i].d = crt;
	}

	sort(a + 1, a + n + 1, comp2);

	for (int i = 1; i <= m; ++i)
		c[i] = (long long)1 << 60;

	for (int i = 1; i <= n; ++i) {
		int tmp = query(1, 1, n, max(1, a[i].s - 1), max(1, a[i].d - 1));
		
		if (c[n + a[i].d - 1] > tmp + a[i].c) {
			update(a[i].d + n - 1, c[a[i].d] - tmp + a[i].c);
			c[a[i].d + n - 1] = tmp + a[i].c;
		}
	}

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

	return 0;
}