Cod sursa(job #348420)

Utilizator andrei.12Andrei Parvu andrei.12 Data 15 septembrie 2009 19:28:16
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.68 kb
#include<stdio.h>
#include<algorithm>

using namespace std;

#define lg 100005
#define inf 0x3f3f3f3f
#define ii pair<int, int>
#define x first
#define y second

int n, i, ind, poz;
long long cnt[lg], d[lg], val;

struct citire{
	int x, c, s, d;
} v[lg], w[lg];

inline int cmp1(citire a, citire b){
	return a.x < b.x;
}
inline int cmp2(citire a, citire b){
	if (a.s != b.s)
		return a.s < b.s;
	return a.d < b.d;
}

int caut1(int val){
	int li = 1, ls = n, x, gs = -1;

	while (li <= ls){
		x = (li+ls) / 2;

		if (v[x].x >= val){
			gs = x;
			ls = x-1;
		}
		else
			li = x+1;
	}

	return gs;
}
int caut2(int val){
	int li = 1, ls = n, x, gs = -1;

	while (li <= ls){
		x = (li+ls) / 2;

		if (v[x].x <= val){
			gs = x;
			li = x+1;
		}
		else
			ls = x-1;
	}

	return gs;
}
void update(int poz, long long val){
	for (; poz; poz -= (poz ^ (poz-1)) & poz)
		cnt[poz] = min(cnt[poz], val);
}
int find(int poz){
	long long gs = 20000000000LL;
	for (; poz <= n; poz += (poz ^ (poz-1)) & poz)
		gs = min(gs, cnt[poz]);

	return gs;
}

int main()
{
	freopen("stalpi.in", "rt", stdin);
	freopen("stalpi.out", "wt", stdout);

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

		w[i].s = v[i].x-v[i].s, w[i].d = v[i].x+v[i].d, w[i].x = v[i].c;
	}

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

	for (i = 1; i <= n; i ++)
		cnt[i] = d[i] = 20000000000LL;
	for (i = 1; i <= n; i ++){
		poz = caut1(w[i].s) - 1;
		ind = caut2(w[i].d);

		if (!poz)
			val = 0;
		else
			val = find(poz);

		val += w[i].x;

		if (val < d[ind]){
			d[ind] = val;
			update(ind, val);
		}
	}

	//for (i = 1; i <= n; i ++)
	//	printf("%lld\n", d[i]);

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

	return 0;
}