Cod sursa(job #734053)

Utilizator danalex97Dan H Alexandru danalex97 Data 13 aprilie 2012 14:23:24
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.67 kb
/* 

// 60 p
#include <fstream>
#include <algorithm>
using namespace std;

#define MaxN 100000
#define oo MaxN*MaxN

#define one first
#define two second

#define X one.one
#define C one.two
#define S two.one
#define D two.two

#define PP pair < pair<int,int>,pair<int,int> >
#define aib(i) ( ( i^(i-1) ) & i )

typedef int AIB[MaxN+11];

PP A[MaxN+11];
int V[MaxN+11];
int N;

AIB Aib;

void update(int pl,int val)
{	
	for ( int i=pl;i<=N;i+=aib(i) )
		Aib[i]+=val; 
}

int seek(int x)
{   
	int rez=0; 
	for ( int i=x;i>0;i-=aib(i) )
		rez+=Aib[i];
	return rez;
}

int binfire(int sum)
{
	int st=1,dr=N,mid,x;
    
	while ( dr>st )
	{
        mid=(st+dr) /2;
        x=seek(mid);
        
		if ( x>sum )
			dr=mid-1; 
		else
			if ( x<sum )
				st=mid+1; 
			else 
				return mid;
	}
    
	return ( seek(st)==sum ) ? st : -1 ;
}

bool cmp(PP A,PP B)
{return ( A.X < B.X || ( A.X == B.X && A.X + A.D < B.X + B.D ) );}

int main(void)
{
	ifstream F("stalpi.in");
	ofstream G("stalpi.out");
	
	F>>N;
	for (int i=1;i<=N;++i)
		F>>A[i].X>>A[i].C>>A[i].S>>A[i].D;
	
	sort(A,A+N+1,cmp);
	for (int i=1;i<=N;++i) 
		V[i] = A[i].X + A[i].D;
	sort(V,V+N+1);
	
	for (int i=1;i<=N;++i)
		Aib[i]=oo;
	
	for (int i=1;i<=N;++i)
	{
		Aib[i]=A[i].S;
		int a=A[i].X-A[i].D;
		
		if( a > A[1].X )
			Aib[i] += seek ( binfire(a) ) ;
		update( binfire ( A[i].X + A[i].S + 1 ) , Aib[i] );
	}
	
	G<<seek( binfire (A[N].X + 1) );
	
	F.close();
	G.close();
}

*/

/*

// 0p :(

using namespace std;

#include<cstdio>
#include<cstring>
#include<algorithm>

#define Nm (1<<17)
#define Inf (1ll<<60)
#define md (l+r>>1)
#define ls (n<<1)
#define rs (n<<1|1)
#define min(a,b) ((a)<(b)?(a):(b))

int X[Nm],n;
long long M[Nm<<1];
struct interval
{
    int a,b,c;
} I[Nm];

void read()
{
    char S[40];
    int i,j;

    freopen("stalpi.in","r",stdin);
    scanf("%d ",&n);
    for(i=0;i<n;++i)
    {
        gets(S);
        for(j=0;S[j]!=' ';++j)
            X[i]=X[i]*10+S[j]-'0';
        for(++j;S[j]!=' ';++j)
            I[i].c=I[i].c*10+S[j]-'0';
        for(++j;S[j]!=' ';++j)
            I[i].a=I[i].a*10+S[j]-'0';
        for(++j;S[j];++j)
            I[i].b=I[i].b*10+S[j]-'0';
        I[i].a=X[i]-I[i].a;
        I[i].b+=X[i];
    }
}

bool cmp(interval a, interval b)
{
    return a.a<b.a;
}

void build(int n, int l, int r)
{
    M[n]=Inf;
    if(l<r)
    {
        build(ls,l,md);
        build(rs,md+1,r);
    }
}

int p;
long long ans;

void query(int n, int l, int r)
{
    ans=min(ans,M[n]);
    if(l==r)
        return;
    if(p<=md)
        query(ls,l,md);
    else
        query(rs,md+1,r);
}

int a,b;
long long v;

void update(int n, int l, int r)
{
    if(a<=l && r<=b)
    {
        M[n]=min(M[n],v);
        return;
    }
    if(a<=md)
        update(ls,l,md);
    if(b>md)
        update(rs,md+1,r);
}

void solve()
{
    int i,j=0,step,s;

    sort(X,X+n);
    sort(I,I+n,cmp);
    build(1,0,n-1);

    for(step=1;step<=n;step<<=1); step>>=1;

    for(i=0;i<n;++i)
    {
        if(I[j].a>X[i])
            continue;
        if(i)
        {
            p=i-1; ans=Inf;
            query(1,0,n-1);
        }
        else
            ans=0;

        a=i;
        for(;I[j].a<=X[i];++j)
        {
            b=i-1;
            for(s=step;s;s>>=1)
                if(b+s<n && X[b+s]<=I[j].b)
                    b+=s;
            if(a<=b)
            {
                v=ans+I[j].c;
                update(1,0,n-1);
            }
        }
    }

    p=n-1; ans=Inf;
    query(1,0,n-1);
}

void write()
{
    freopen("stalpi.out","w",stdout);
    printf("%lld\n",ans);
}

int main()
{
    read();
    solve();
    write();
    return 0;
}
*/

#include <iostream>
#include <fstream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define INF 0x3f3f3f3f
#define N_max 100001
int N, S[N_max], best[N_max];
int Arb[4*N_max+66], Val, Pos, start, finish, minim;
struct Stalpi 
{
    int x, c, st, dr;
} P[N_max];

int cmp(Stalpi a, Stalpi b) 
{
    if(a.dr!=b.dr) return a.dr<b.dr;
}

void Update(int nod, int left, int right) 
{
     if(left==right)
	 {
          Arb[nod]=Val;
          return;
     }
     
     int mij=(left+right)/2;
     if(Pos<=mij) Update(2*nod, left, mij);
     else Update(2*nod+1, mij+1, right);
     
     Arb[nod]=min(Arb[2*nod], Arb[2*nod+1]);
}

void Query(int nod, int left, int right) 
{
     if(start<=left && right<=finish) 
	 {
          minim=min(minim, Arb[nod]);
          return;
     }
     
     int mij=(left+right)/2;
     if(start<=mij) Query(2*nod, left, mij);
     if(mij<finish) Query(2*nod+1, mij+1, right);
}

int main() 
{
    FILE *f1=fopen("stalpi.in", "r"), *f2=fopen("stalpi.out", "w");
    int i, j, p, q, c, L, R;
    fscanf(f1, "%d\n", &N);
    for(i=1; i<=N; i++) 
	{
         fscanf(f1, "%d %d %d %d\n", &P[i].x, &P[i].c, &P[i].st, &P[i].dr);
         S[i]=P[i].x;
         P[i].st=P[i].x-P[i].st;
         P[i].dr=P[i].x+P[i].dr;
    }
    S[0]=-INF;
    sort(S, S+N+1);
    sort(P+1, P+N+1, cmp);
    memset(best, INF, sizeof(best));
    memset(Arb, INF, sizeof(Arb));
    Val=0; Pos=0; Update(1, 0, N); 
    best[0]=0;
    for(i=1; i<=N; i++) 
	{
         L=lower_bound(S, S+N+1, P[i].st)-S-1;
         R=lower_bound(S, S+N+1, P[i].dr+1)-S-1;
         start=L; finish=N; minim=INF;
         Query(1, 0, N);
         best[R]=min(best[R], minim + P[i].c);
         Val=best[R]; Pos=R;
         Update(1, 0, N);
    }
    fprintf(f2, "%d\n", best[N]);
    fclose(f1); fclose(f2);
    return 0;
}