Cod sursa(job #177606)

Utilizator moga_florianFlorian MOGA moga_florian Data 13 aprilie 2008 12:55:33
Problema Stalpi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.42 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;

void find_min(int i,int li,int lf, int st, int dr){

	if(lf < st || dr < li)
	    return;

	if(st <= li && lf <= dr){
		if(arb[i] < MIN)
		    MIN = arb[i];
		return;
	}
	
	int mij = (li+lf)/2;
	if(ult[i]){
		arb[2*i] = arb[2*i+1] = arb[i];
		ult[2*i] = ult[2*i+1] = 1;
		ult[i] = 0;
	}
	
	find_min(2*i,li,mij,st,dr);
	find_min(2*i+1,mij+1,lf,st,dr);

}

void update(int i, int li,int lf, int st, int dr, int val){

	if(lf<st || dr<li)
	    return;
	    
	if(st <= li && lf <= dr){
		if(!ult[i]){
			int mij = (li+lf)/2;
			update(2*i,li,mij,st,dr,val);
			update(2*i+1,mij+1,lf,st,dr,val);
		}
		else
			if(ult[i] && arb[i] > val){
			    arb[i] = val;
			    ult[i] = 1;
			}
		return;
	}
	
	int mij = (li+lf)/2;
	if(ult[i]){
		arb[2*i] = arb[2*i+1] = arb[i];
		ult[2*i] = ult[2*i+1] = 1;
		ult[i] = 0;
	}
	
	update(2*i,li,mij,st,dr,val);
	update(2*i+1,mij+1,lf,st,dr,val);
	
	arb[i] = arb[2*i];
	if(arb[2*i+1] < arb[i])
	    arb[i] = arb[2*i+1];
	
}

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);
	*/
	
	arb[1] = inf;
	ult[1] = 1;
	
	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
		MIN = inf;
		find_min(1,1,N,L,N);
		
		if(MIN == inf)
		    MIN = 0;
		MIN += A[i].c;
		update(1,1,N,1,R,MIN);
		
	}
	
	MIN = inf;
	find_min(1,1,N,N,N);
	
	fprintf(fout,"%lld\n",MIN);
	
	fclose(fin);
	fclose(fout);
	return 0;
	
}