Cod sursa(job #315952)

Utilizator anna_bozianuBozianu Ana anna_bozianu Data 17 mai 2009 18:52:43
Problema Stalpi Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.56 kb
#include<stdio.h> 
#include<utility>
#include<algorithm>
#include<vector>
#define DV 100010
#define DA 270000
using namespace std;
vector< pair< int,long long > > pd[DV];
int n,i,A,B,zero,da;
long long INF=1,C,best[DA],a[DA],b[DA],bst(int nod);
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()   
{
	int poz,tata,fs,fd;
	long long minold,minnew;
	vector< pair< int,long long > >::iterator it;
	build_arb();
	for(i=1;i<=n;i++)
	{
		for(it=pd[i].begin();it!=pd[i].end();it++)
		{
			A=(*it).first-1;B=i-1;
			C=INF;
			C=bst(1);
			C+=(*it).second;
			poz=zero+i;   
            if(C>=best[poz])continue;
			best[poz]=C;   
            tata=poz>>1;   
            while(tata)   
            { fs=tata<<1;   
              fd=fs+1;   
              minold=best[tata];   
              minnew=(best[fs]<best[fd])?best[fs]:best[fd];   
              if(minnew==minold)break;   
              best[tata]=minnew;   
              tata>>=1;   
            }
		}
	}
	printf("%lld\n",best[zero+n]);
}
void build_arb()
{
	int fs,fd;
	zero=1;   
    while(zero<n+1)zero<<=1;   
    for(i=0;i<=n;i++){a[zero+i]=i;b[zero+i]=i;best[zero+i]=INF;}
    for(i=n+1;i<=zero;i++)a[zero+i]=b[zero+i]=i;
    best[zero]=0;   
    for(i=zero-1;i>=1;i--)   
    { fs=(i<<1);fd=fs+1;a[i]=a[fs];b[i]=b[fd];   
      best[i]=(best[fs]<best[fd])?best[fs]:best[fd];   
    }   
}
long long  bst(int pa)   
{   long long bst1,bst2;   
    if(A>b[pa])return INF;   
    if(B<a[pa])return INF;   
    if(A<=a[pa]&&b[pa]<=B) return best[pa];   
    bst1=bst(pa<<1);   
    bst2=bst((pa<<1)|1);   
    bst1=(bst1<bst2)?bst1:bst2;   
    return bst1;   
}