Cod sursa(job #899502)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 28 februarie 2013 14:53:12
Problema Stalpi Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.91 kb
#include<stdio.h>
#include<algorithm>

#define maxn 100005
#define inf (1LL<<62)

using namespace std;

FILE*f=fopen("stalpi.in","r");
FILE*g=fopen("stalpi.out","w");

int n,a,b,pos;
long long D[maxn],Arb[4*maxn],Ad[4*maxn],best,val;

struct stalp{
	int x;
	int s,d;
	int c;
}S[maxn];

struct cmp{
	inline bool operator () ( const stalp &a , const stalp &b ){
		return a.x < b.x;
	}
};

void init ( int nod , int st , int dr ){
	
	Arb[nod] = Ad[nod] = inf;
	if ( st == dr )	return ;
	
	int mij = (st+dr)>>1;
	int nodst = nod<<1;
	int noddr = nodst|1;
	
	init(nodst,st,mij);
	init(noddr,mij+1,dr);
}

inline int cb1 ( int right , int val ){
	
	int left = 1,middle;
	while ( left <= right ){
		middle = (left+right)>>1;
		if ( val <= S[middle].x ){
			right = middle-1;
		}
		else{
			left = middle+1;
		}
	}
	
	return left;
}

inline int cb2 ( int left , int val ){
	
	int middle,right = n;
	while ( left <= right ){
		middle = (left+right)>>1;
		if ( S[middle].x <= val ){
			left = middle+1;
		}
		else{
			right = middle-1;
		}
	}
	
	return right;
}

void update ( int nod , int st , int dr ){
	
	if ( a <= st && dr <= b ){
		Ad[nod] = min(Ad[nod],val);
		Arb[nod] = min(Arb[nod],val);
		return ;
	}
	
	int mij = (st+dr)>>1;
	int nodst = nod<<1;
	int noddr = nodst|1;
	
	Ad[nodst] = min(Ad[nodst],Ad[nod]);
	Ad[noddr] = min(Ad[noddr],Ad[nod]);
	Arb[nod] = min(Arb[nod],Ad[nod]);
	Ad[nod] = inf;
	
	if ( a <= mij ){
		update(nodst,st,mij);
	}
	if ( b > mij ){
		update(noddr,mij+1,dr);
	}
	Arb[nod] = min(Arb[nod],min(Arb[nodst],Arb[noddr]));
	Arb[nod] = min(Arb[nod],min(Ad[nodst],Ad[noddr]));
}

void query_int ( int nod , int st , int dr ){
	
	if ( a <= st && dr <= b ){
		best = min(best,Arb[nod]);
		best = min(best,Ad[nod]);
		return ;
	}
	
	int mij = (st+dr)>>1;
	int nodst = nod<<1;
	int noddr = nodst|1;
	
	Ad[nodst] = min(Ad[nodst],Ad[nod]);
	Ad[noddr] = min(Ad[noddr],Ad[nod]);
	Arb[nod] = min(Arb[nod],Ad[nod]);
	Ad[nod] = inf;
	
	if ( a <= mij ){
		query_int(nodst,st,mij);
	}
	if ( b > mij ){
		query_int(noddr,mij+1,dr);
	}
	Arb[nod] = min(Arb[nod],min(Arb[nodst],Arb[noddr]));
	Arb[nod] = min(Arb[nod],min(Ad[nodst],Ad[noddr]));
}

int main () {
	
	fscanf(f,"%d",&n);
	for ( int i = 1 ; i <= n ; ++i ){
		
		fscanf(f,"%d %d %d %d",&S[i].x,&S[i].c,&S[i].s,&S[i].d);
	}
	
	sort(S+1,S+n+1,cmp());
	
	init(1,1,n);
	
	for ( int i = 1 ; i <= n ; ++i ){
		D[i] = inf;
	}
	
	for ( int i = 1 ; i <= n ; ++i ){
		
		best = inf;
		a = b = i; query_int(1,1,n); D[i] = best;
		int left = cb1(i,S[i].x-S[i].s);
		a = left-1,b = i-1;
		best = inf;
		if ( !a ){
			best = 0;
		}
		else{
			query_int(1,1,n);
		}
		
		D[i] = min(D[i],best+S[i].c);
		int right = cb2(i,S[i].x+S[i].d);
		a = i,b = right; val = best+S[i].c;
		update(1,1,n);
	}
	
	fprintf(g,"%lld\n",D[n]);
	
	fclose(f);
	fclose(g);
	
	return 0;
}