Cod sursa(job #291731)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 30 martie 2009 11:57:38
Problema Stalpi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.43 kb
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <algorithm>
using namespace std;

#define maxN	100100
#define maxK	300100
#define maxV	1200300
#define oo	20000000000000LL
#undef DEBUG
struct stalp {
	int P, C, St, Dr;
} V[maxN], A[maxN];
int N;
int start, finish, poz, level[maxN];
long long Arb[maxK * 4 + 100], SolQuery, val;

inline bool cmp2 (stalp a, stalp b) {
	return a.P < b.P;
}
inline bool cmp (stalp a, stalp b) {
	return a.P - a.St < b.P - b.St;
}
int lower_bound_x (int nr, int now) {
	int st = 0, dr = N + 1, m = (st + dr) >> 1, Sol = 0;
	nr = max(nr, 0);
	while (st < dr - 1) {
		if (V[m].P <= nr) {
			st = m;
			Sol = m;
		}
		else
			dr = m;
		m = (st + dr) >> 1;
	}
	return Sol;
}

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


void query ( int frunza) {
	int nod;
	SolQuery = oo;
	for ( nod = level[frunza]; nod; nod >>= 1)
		if (Arb[nod] < SolQuery) {
			SolQuery = Arb[nod];
		}
}

void update (int nod, int l, int r) {
	if (start <= l && r <= finish) {
		if (Arb[nod] > val)
			Arb[nod] = val;
		return ;
	}
	int m = (l + r) >> 1;
	if (start <= m)
		update(nod * 2, l, m);
	if (m < finish)
		update(nod * 2 + 1, m + 1, r);
	//Arb[nod] = minIm(Arb[nod * 2], Arb[nod * 2 + 1]);
}

void explore (int nod, int l, int r) {
	if (l == r) {
		level[l] = nod;
		return ;
	}
	int m = (l + r) >> 1;
	explore(nod * 2, l, m);
	explore(nod * 2 + 1, m + 1, r);
}

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

	scanf("%d", &N);
	
	for (i = 1; i <= N; ++ i) {
		scanf("%d%d%d%d", &A[i].P, &A[i].C, &A[i].St, &A[i].Dr);
		V[i] = A[i];
	}

	sort (A + 1, A + N + 1, cmp);
	sort (V + 1, V + N + 1, cmp2);
	for (i = 1; i <= maxV; ++ i)
		Arb[i] = oo;
		
	explore(1, 1, 3 * N);

#ifdef DEBUG
	for (i = 1; i <= N; ++ i)
		printf("%d %d %d %d\n", A[i].P, A[i].C, A[i].St, A[i].Dr);
	puts("");
	for (i = 1; i <= N; ++ i)
		printf("%d %d %d %d\n", V[i].P, V[i].C, V[i].St, V[i].Dr);
#endif
	for (i = 1; i <= N; ++ i) {
		x = lower_bound_x(A[i].P - A[i].St , i);
		y = lower_bound_x(A[i].P + A[i].Dr, i);
		fprintf(stderr, "%d %d\n", x, y);
		query (x);
		if (SolQuery == oo)
			SolQuery = 0;
		assert (SolQuery != oo);
		val = SolQuery + A[i].C;
		start = x; finish = y;
		update (1, 1, 3 * N);
	}
#ifdef DEBUG
	for (i = 0; i < 5; ++ i) {
		for (j = (1 << i); j < (2 << i); ++ j)
			printf("%lld ", Arb[j]);
		puts("");
	}
#endif
	query (N);
	printf("%lld\n", SolQuery);
	while(1);
}