Cod sursa(job #315505)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 16 mai 2009 08:14:23
Problema Stalpi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include<stdio.h>
#define DA 1<<18
#define DV 1<<17
#define INF 1LL<<62
int n,i,nn,x[DV],s[DV],d[DV],A[DA],B[DA],ords(int i1,int i2),zero,imax,poz,nod;
long long c[DV],b[DA],val,get_min(int NOD,int AA,int BB),sol;
void readd(),solve(),sortx(),sorts(),hdx(int ic,int nc),swx(int i1,int i2),
hds(int ic,int nc),sws(int i1,int i2),getsd(),make_arb(),solve_poz();
int main()
{
	readd();
	solve();
	return 0;
}
void readd()
{
	freopen("stalpi.in","r",stdin);
	freopen("stalpi.out","w",stdout);
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%d%d%d%lld",&x[i],&s[i],&d[i],&c[i]);
		s[i]=x[i]-s[i];d[i]=x[i]+d[i];
	}
}
void solve()
{
	sortx();
	sorts();
	for(i=1;i<=n;i++)getsd();
	for(i=1;i<=n;i++)
	{
		if(s[i]>s[i-1]){s[++nn]=s[i];d[nn]=d[i];c[nn]=c[i];continue;}
		if(d[i]>d[i-1]){s[++nn]=s[i];d[nn]=d[i];c[nn]=c[i];continue;}
	}
	make_arb();
	while(poz<=nn)solve_poz();
	sol=b[zero+n];
	printf("%lld\n",sol);
}
void sortx()
{
	for(i=n/2;i>=1;i--)hdx(i,n);
	for(i=n;i>=2;i--){swx(1,i);hdx(1,i-1);}
}
void sorts()
{
	for(i=n/2;i>=1;i--)hds(i,n);
	for(i=n;i>=2;i--){sws(1,i);hds(1,i-1);}
}
void hdx(int ic,int nc)
{
	int is=ic<<1;
	if(is>nc)return;
	if(is<nc)if(x[is]<x[is+1])is++;
	if(x[ic]<x[is]){swx(is,ic);hdx(is,nc);}
}
void hds(int ic,int nc)
{
	int is=ic<<1;
	if(is>nc)return;
	if(is<nc)if(ords(is,is+1))is++;
	if(ords(ic,is)){sws(is,ic);hds(is,nc);}
}
int ords(int i1,int i2)
{
	return 
	s[i1]<s[i2]||
	(s[i1]==s[i2]&&d[i1]<d[i2])||
	(s[i1]==s[i2]&&d[i1]==d[i2]&&c[i1]<c[i2]);
}
void swx(int i1,int i2)
{
	x[i1]^=x[i2]^=x[i1]^=x[i2];
}
void sws(int i1,int i2)
{
	s[i1]^=s[i2]^=s[i1]^=s[i2];
	d[i1]^=d[i2]^=d[i1]^=d[i2];
	c[i1]^=c[i2]^=c[i1]^=c[i2];
}
void getsd()
{
	int ll,rr,mm;
	ll=0;rr=n;
	while(rr-ll-1)
	{
		mm=(rr+ll)>>1;
		if(s[i]<=x[mm])rr=mm;
		else ll=mm;
	}
	s[i]=rr;
	ll=0;rr=n+1;
	while(rr-ll-1)
	{
		mm=(rr+ll)>>1;
		if(d[i]>=x[mm])ll=mm;
		else rr=mm;
	}
	d[i]=ll;
}
void make_arb()
{
	int FS,FD;
	imax=1;
	while(imax<=n)imax<<=1;imax<<=1;
	zero=imax>>1;zero--;
	for(i=imax-1;i>=1;i--)b[i]=INF;
	for(i=zero+1;i<imax;i++) A[i]=B[i]=i-zero;
	for(i=zero;i>=1;i--)
	{
		FS=i<<1;FD=FS|1;
		A[i]=A[FS];B[i]=B[FD];
	}
	poz=1;
	while(s[poz]==1&&poz<=nn)
	{
		nod=zero+d[poz];
		val=c[d[poz]];
		while(val<b[nod]){b[nod]=val;nod>>=1;}
		poz++;
	}
	
}
void solve_poz()
{
	val=get_min(1,s[poz]-1,d[poz]-1);
	val=val+c[d[poz]];
	nod=zero+d[poz];
	while(nod&&val<b[nod]){b[nod]=val;nod>>=1;}
	poz++;
}
long long get_min(int NOD,int AA,int BB)
{
	int FS,FD;
	long long val1,val2;
	if(AA>B[NOD])return INF;
	if(BB<A[NOD])return INF;
	if(AA<=A[NOD]&&B[NOD]<=BB)return b[NOD];
	FS=NOD<<1;
	FD=FS|1;
	val1=get_min(FS,AA,BB);
	val2=get_min(FD,AA,BB);
	return val1<val2?val1:val2;
}