Cod sursa(job #137639)

Utilizator diac_paulPaul Diac diac_paul Data 17 februarie 2008 12:51:08
Problema Stalpi Scor 20
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasele 11-12 Marime 1.7 kb
#include <stdio.h>
#include <stdlib.h>
#define NMax 200005
#define INF 1000000000

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

stalp v[NMax];
int n, cmin, c[NMax], ci[NMax], sq;

void read();
void solve();
void write();
int comp(const void *a, const void *b)
{ return (*(stalp*)a).x - (*(stalp*)b).x; }
int cauta(int x);

int main()
{
	read();
	solve();
	write();

	return 0;
}

void solve()
{
	int i, j, k, cj;

	for (sq = 2; sq * sq <= n; sq++);

	for (i = 0; i < n; i++)
	{
		c[i] = INF;
		ci[i] = INF;
	}

	qsort(v, n, sizeof(v[0]), comp);

	for (i = 0; i < n; i++)
	{
		// aprind bec i

		j = cauta(v[i].x - v[i].s); // j ultimul copac nerezolvat

		//aflu minimul pe [j, n-1]
		if (j == -1)
			cj = 0;
		else
		{
			cj = INF;

			for (k = j; k % sq != 0; k++)
			{
				if (cj > c[k])
					cj = c[k];
			}

			for (; k < n; k += sq)
			{
				if (cj > ci[k / sq])
					cj = ci[k / sq];
			}
		}

		j = cauta(v[i].x + v[i].d + 1); // ultimul copac rezolvat
		
		if (c[j] > cj + v[i].c)
			c[j] = cj + v[i].c;

		if (ci[j / sq] > cj + v[i].c)
			ci[j / sq] = cj + v[i].c;
	}

	cmin = c[n-1];
}

int l, h, mj;
int cauta(int x)
{
	l = 0;
	h = n-1;

	while (h - l > 1)
	{
		mj = (l + h) / 2;

		if (v[mj].x > x)
			h = mj;
		else
			l = mj;
	}
	while (l < n - 1 && v[l + 1].x <= x)
		l++;
	if (v[0].x >= x)
		return -1;
	else
		return l;
}

void read()
{
	FILE *fin = fopen("stalpi.in", "rt");
	fscanf(fin, "%d", &n);
	for (int i = 0; i < n; i++)
		fscanf(fin, "%d %d %d %d", &v[i].x, &v[i].c, &v[i].s, &v[i].d);
}

void write()
{
	FILE *fout = fopen("stalpi.out", "wt");
	fprintf(fout, "%d\n", cmin);
	fclose(fout);
}