Cod sursa(job #488063)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 27 septembrie 2010 16:51:30
Problema Stalpi Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.01 kb
#include <stdio.h>
#include <algorithm>
#define Nmax 100002
#define INF 1000000000
#define BIG 10000000000000LL
#define Amax (1<<18)+1
#define LL long long

using namespace std;

int X[Nmax],S[Nmax],D[Nmax],C[Nmax],ind1[Nmax],ind2[Nmax];
LL din[Nmax];
LL Arb[Amax];
int N,wh,mn;

inline LL Minim(LL x,LL y){ return x<y ? x:y; }
inline LL Maxim(LL x,LL y){ return x>y ? x:y; }
inline int cmp1(int i,int j){
	return X[i] < X[j];
}
inline int cmp2(int i,int j){
	return S[i] < S[j];
}
inline int caut_stanga(int s){
	int l=1,r=N,m,rez=0;
	while( l<=r ){
		m=(l+r)>>1;
		if( X[ind1[m]] >= s )
			r=m-1;
		else rez=m, l=m+1;
	}
	return rez;
}
inline int caut_dreapta(int d){
	int l=1,r=N,m,rez=N;
	while( l<=r ){
		m=(l+r)>>1;
		if( X[ind1[m]] <= d )
			rez=m, l=m+1;
		else r=m-1;
	}
	return rez;
}

inline void Update(int nod,int l,int r,int poz,int val){
	if( l==r ){
		Arb[nod]=Minim(Arb[nod],val);
		return;
	}
	int m=(l+r)>>1;
	if( poz<=m ) Update(nod<<1,l,m,poz,val); 
	else Update((nod<<1)+1,m+1,r,poz,val);
	Arb[nod]=Minim(Arb[nod],Minim(Arb[2*nod],Arb[2*nod+1]));
}
inline void Query(int nod,int l,int r,int x,int y){
	if( x<=l && r<=y ){
		mn=Minim(mn,Arb[nod]);
		return;
	}
	int m=(l+r)>>1;
	if( x<=m ) Query(nod<<1,l,m,x,y);
	if( m <y ) Query((nod<<1)+1,m+1,r,x,y);
}
	

int main(){
	int i,L,R;
	freopen("stalpi.in","r",stdin);
	freopen("stalpi.out","w",stdout);
	scanf("%d",&N);
	for(i=1;i<=N;++i){
		scanf("%d%d%d%d",&X[i],&C[i],&S[i],&D[i]);
		S[i]=Maxim(X[i]-S[i],1), D[i]=Minim(D[i]+X[i],INF);
		ind1[i]=ind2[i]=i;
	}
	
	sort(ind1+1,ind1+1+N,cmp1); // dupa x
	sort(ind2+1,ind2+1+N,cmp2); // dupa s
	
	for(i=1;i<=N;++i) din[i]=BIG;
	for(i=1;i<Amax;++i) Arb[i]=BIG;
	
	for(i=1;i<=N;++i){
		wh=ind2[i];
		L=caut_stanga(S[wh]);
		R=caut_dreapta(D[wh]);
		
		mn=BIG;
		if(L==0) mn=0; 
		else Query(1,1,N,L,R);
		
		din[R]=Minim(din[R],mn+C[wh]);
		
		Update(1,1,N,R,din[R]);
	}
	
	printf("%lld\n",din[N]);
	fclose(stdin); fclose(stdout);
	return 0;
}