Cod sursa(job #289196)

Utilizator toni2007Pripoae Teodor Anton toni2007 Data 26 martie 2009 15:37:32
Problema Stalpi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.85 kb
#include <cstdio>
#include <cstdlib>
#include <map>
#include <algorithm>
#include <vector>
#include <cassert>

using namespace std;

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

inline bool cmp (stalp a, stalp b) {
	if (a.P != b.P)
		return a.P < b.P;
	return a.St < b.St;
}

void normalizare () {
	vector < int > Tmp;
	vector < int > :: iterator it;
	stalp now;
	int i;
	
	for (i = 1; i <= N; ++ i) {
		Tmp.push_back(A[i].P);
		Tmp.push_back(A[i].P - A[i].St);
		Tmp.push_back(A[i].P + A[i].Dr);
	}
	
	sort(Tmp.begin(), Tmp.end());
	it = unique(Tmp.begin(), Tmp.end());
	Tmp.resize(it - Tmp.begin());
	for (i = 0; i < Tmp.size(); ++ i)	MyMap[Tmp[i]] = i + 1;
	
	for (i = 1; i <= N; ++ i) {
		now.P = MyMap[A[i].P];
		now.St = MyMap[A[i].P - A[i].St];
		now.Dr = MyMap[A[i].P + A[i].Dr];
		now.C = A[i].C;
		A[i] = now;
	}
}

int lower_bound_x (int nr, int now) {
	int st = 1, dr = now - 1, m = (st + dr) / 2;
	
	while (st < dr) {
		if (A[m].P > nr)
			dr = m - 1;
		else
			st = m + 1;
		m = (st + dr) / 2;
	}
	while (m > 0 && A[m].P > nr)	--m;
	return m;
}

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] != oo) {
			SolQuery = Arb[nod];
			return ;
		}
}

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;
	
	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);

	normalizare();
	sort (A + 1, A + N + 1, cmp);

	for (i = 1; i <= maxV; ++ i)
		Arb[i] = oo;
		
	explore(1, 1, 3 * N);
	start = A[1].St; finish = A[1].Dr; val = A[1].C;
	update(1, 1, 3 * N);

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