Cod sursa(job #315925)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 17 mai 2009 17:23:24
Problema Stalpi Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.21 kb
#include<stdio.h> 
#include<utility>
#include<algorithm>
#include<vector>
#define DV 100010
#define DA 250000
using namespace std;
vector< pair< int,long long > > pd[DV];
int n,i,A,B,zero,da;
long long INF=1,C,best[DA],bst(int nod,int a,int b);
void readd(),solve(),build_arb();
int main()   
{   
    readd();   
    solve();   
    return 0;   
}   
void readd()   
{
	int x[DV],s[DV],d[DV],yes,no,maybe;
	long long c[DV];
	pair<int,long long> per;
	vector< pair< int,long long > >::iterator it;
	freopen("stalpi.in","r",stdin);   
    freopen("stalpi.out","w",stdout);   
    scanf("%d",&n);   
    for(i=1;i<=n;i++)   
    {   
        scanf("%d%lld%d%d",&x[i],&c[i],&s[i],&d[i]);
		s[i]=x[i]-s[i];d[i]=x[i]+d[i];INF+=c[i];
	}
	sort(x+1,x+n+1);
	for(i=1;i<=n;i++)
	{
		if(s[i]<=x[1])yes=1;
		else 
		{
			no=1;yes=n;
			while(yes-no>1)
			{
				maybe=(yes+no)/2;
				if(s[i]>x[maybe])no=maybe;
				else yes=maybe;
			}
		}
		s[i]=yes;
		if(d[i]>=x[n])yes=n;
		else
		{
			no=n;yes=1;
			while(no-yes>1)
			{
				maybe=(yes+no)/2;
				if(d[i]>=x[maybe])yes=maybe;
				else no=maybe;
			}
		}
		per.first=s[i];
		per.second=c[i];
		pd[yes].push_back(per);
	}
}   
void solve()   
{
	vector< pair< int,long long > >::iterator it;
	int Nod,fiu;
	build_arb();//arbore de intervale!!
	//interval cercetat [0,i-1] la fiecare pas
	//se face update pe intervalele care contin valoarea la care fac update
	//o=zero
	//
	for(i=1,Nod=zero+1;i<=n;i++,Nod++)
	{
		best[Nod]=INF;
		for(it=pd[i].begin();it!=pd[i].end();it++)
		{
			A=(*it).first-1;B=i-1;
			C=INF;
			C=bst(1,0,n);
			C+=(*it).second;
			if(C>=best[Nod])continue;
			best[Nod]=C;
			for(fiu=Nod;fiu>=2;fiu/=2)
				best[fiu>>1]=best[fiu]<best[fiu+1]?best[fiu]:best[fiu+1];
		}
	}
	printf("%lld\n",best[zero+n]);
}
void build_arb()
{
	da=1;
	while(n+1>da)da<<=1;
	zero=da;da<<=1;
	for(i=da;i;i--)best[i]=INF;
	for(i=zero;i;i>>=1)best[i]=0;
}
long long bst(int nod,int a,int b)
{
	int m;
	long long bst1,bst2;
	if(B<a)return INF;//[A,B]->[a,b];
	if(b<A)return INF;//[a,b]->[A,B];
	if(A<=a&&b<=B)return best[nod];
	m=(a+b)/2;
	bst1=bst(2*nod,a,m);
	bst2=bst(2*nod+1,m+1,b);
	return bst1<bst2?bst1:bst2;
}