Cod sursa(job #283129)

Utilizator alex_mircescuAlex Mircescu alex_mircescu Data 18 martie 2009 19:34:45
Problema Stalpi Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.26 kb
#include <stdio.h>
#include <algorithm>
#include <vector>

using namespace std;

#define INF 20000000000000000LL
#define mp make_pair
#define pb push_back
#define BIGINT long long

long n, i, m, c, s, d, j, k, X[100010];
BIGINT a[200010], num, MIN, MIN1;
vector<pair<pair<long, long>, long> > info;

void make(long v1, long v2, long poz) {
	if (i >= v1 && i <= v2) {
		if (a[poz] > num) {
			a[poz] = num;
		}
		if (v1 == v2)
			return;
		make(v1, (v1 + v2) / 2, poz * 2);
		make((v1 + v2) / 2 + 1, v2, poz * 2 + 1);
	}
	return;
}

void query(long v1, long v2, long poz) {
	if (k <= v1 && i - 1 >= v2) {
		if (MIN > a[poz]) {
			MIN = a[poz];
		}
		if (v1 == v2) {
			return;
		}
	} else {
		if (k > v2 || i - 1 < v1) {
			return;
		} else {
			query(v1, (v1 + v2) / 2, poz * 2);
			query((v1 + v2) / 2 + 1, v2, poz * 2 + 1);
		}
	}
	return;
}

void update(long v1, long v2, long poz) {
	if (i >= v1 && i <= v2) {
		if (v1 == v2) {
			a[poz] = num;
			return;
		}
		update(v1, (v1 + v2) / 2, poz * 2);
		update((v1 + v2) / 2 + 1, v2, poz * 2 + 1);
		a[poz] = min(a[poz * 2], a[poz * 2 + 1]);
	} else {
		return;
	}
}

long binary(long num) {
	long l1 = 1, l2 = n + 2, sol, mid;
	while (l1 < l2) {
		mid = (l1 + l2) / 2;
		if (X[mid] <= num) {
			sol = mid;
			l1 = mid + 1;
		} else {
			l2 = mid;
		}
	}
	return sol;
}

int main() {
	freopen("stalpi.in", "r", stdin);
	freopen("stalpi.out", "w", stdout);
	scanf("%ld", &n);
	for (i = 1; i <= n; ++i) {
		scanf("%ld %ld %ld %ld", &X[i + 1], &c, &s, &d);
		info.pb(mp(mp(X[i + 1] + d, X[i + 1] - s), c));
	}
	sort(info.begin(), info.end());
	X[1] = -2000000000;
	sort(X + 2, X + n + 2);

	for (i = 1; i <= 200001; i++)
		a[i] = INF;

	i = 1;
	num = 0;
	make(1, n + 1, 1);
	for (i = 2; i <= n + 1; ++i) {
		num = INF;
		make(1, n + 1, 1);
	}
	for (j = 0; j < n; ++j) {
		i = binary(info[j].first.first);
		k = binary(info[j].first.second - 1);
		MIN = INF;
		query(1, n + 1, 1);
		MIN += info[j].second;
		
		MIN1 = MIN;
		MIN = INF;
		k = i;
		i++;
		query(1, n + 1, 1);
		i--;

		if (MIN1 < MIN) {
			num = MIN1;
			update(1, n + 1, 1);
		}
	}
	MIN = INF;
	k = n + 1;
	i = n + 2;
	query(1, n + 1, 1);
	printf("%lld\n", MIN);
	return 0;
}