Cod sursa(job #177838)

Utilizator moga_florianFlorian MOGA moga_florian Data 13 aprilie 2008 17:37:58
Problema Stalpi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.75 kb
#include<stdio.h>
#define Nmax 100010

int N;
int X[Nmax];
struct nod{int s,d,c;} A[Nmax];

long long arb[3*Nmax];
char ult[3*Nmax];
long long inf = (long long)1000000; * (long long)100000;
long long MIN;
int poz[Nmax];

int best[Nmax];

void init(int i, int li, int lf){

	if(li==lf){
		poz[li] = i;
		return;
	}
	
	int mij = (li+lf)>>1;
	init(2*i,li,mij);
	init(2*i+1,mij+1,lf);

}



int main(){

	FILE *fin = fopen("stalpi.in","r"),
		 *fout = fopen("stalpi.out","w");
		 
	fscanf(fin,"%d",&N);
	
	for(int i=1;i<=N;i++)
	    fscanf(fin,"%d%d%d%d",&X[i],&A[i].c,&A[i].s,&A[i].d);
	    
	for(int i=1;i<=N;i++)
	    A[i].s = X[i] - A[i].s, A[i].d = X[i] + A[i].d;
	    
	//sort A
	for(int i=1;i<=N;i++){
		int j = i;
		while(j/2 && A[j].d > A[j/2].d){
			nod aux = A[j];
			A[j] = A[j/2];
			A[j/2] = aux;
			j>>=1;
		}
	}
	
	int cate = N;
	while(cate > 1){
		nod aux = A[1];
		A[1] = A[cate];
		A[cate] = aux;
		cate --;
		
		int j = 1;
		while(1){
			int k = j<<1;
			if(k>cate) break;
			if(k+1 <= cate && A[k+1].d > A[k].d) k++;
			if(A[j].d >= A[k].d) break;
			
			aux = A[j];
			A[j] = A[k];
			A[k] = aux;
			
			j = k;
		}
	}
	
	//sort X
	for(int i=1;i<=N;i++){
		int j = i;
		while(j/2 && X[j/2] < X[j]){
			int aux = X[j/2];
			X[j/2] = X[j];
			X[j] = aux;
			j>>=1;
		}
	}
	
	cate = N;
	while(cate > 1){
		int aux = X[1];
		X[1] = X[cate];
		X[cate] = aux;
		cate --;
		
		int j = 1;
		while(1){
			int k = j*2;
			if(k>cate) break;
			if(k+1 <= cate && X[k+1] > X[k]) k++;
			if(X[j] >= X[k]) break;
			
			aux = X[j];
			X[j] = X[k];
			X[k] = aux;
			j = k;
		}
	}
	
	/*
	//test
	for(int i=1;i<=N;i++)
	    fprintf(fout,"%d\n",X[i]);

	for(int i=1;i<=N;i++)
	    fprintf(fout,"%d %d\n",A[i].s,A[i].d);
	*/
	
	init(1,1,N);
	
	arb[1] = inf;
	ult[1] = 1;
	
	for(int i=1;i<=N;i++) best[i] = inf;
	
	for(int i=1;i<=N;i++){
		//intervalul A[i].s - A[i].d
		//aflare L si R
		
		int L=-1,R=N+1;
		int li,lf,mij;
		
		li = 1;lf = N;
		while(li<=lf){
			mij = (li+lf) / 2;
			if(X[mij] < A[i].s){
				L = mij;
				li = mij + 1;
			}
			else
				lf = mij - 1;
		}
		
		//if(L < 0) L = 1;
		
		li = 1;lf = N;
		while(li<=lf){
			mij = (li+lf)/2;
			if(X[mij] <= A[i].d){
				R = mij;
				li = mij+1;
			}
			else
			    lf = mij-1;
		}
		//if(R > N) R = N;

		/*
		//test2
		fprintf(fout,"%d %d\n",L,R);
		*/
		
		//procesare
		if(L<0)
			MIN = 0;
		else{
			MIN = inf;
			for(int p = L; p<=N;p++)
				if(best[p] < MIN)
				    MIN = best[p];
		}
		
		MIN += A[i].c;

		for(int i=1;i<=R;i++)
		    if(best[i] > MIN)
				best[i] = MIN;
		
	}
	
	fprintf(fout,"%lld\n",best[N]);
	
	fclose(fin);
	fclose(fout);
	return 0;
	
}