Cod sursa(job #994158)

Utilizator maritimCristian Lambru maritim Data 5 septembrie 2013 00:09:02
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.86 kb
#include<iostream>
#include<fstream>
#include<algorithm>
using namespace std;

ifstream f("stalpi.in");
ofstream g("stalpi.out");

struct stalp
{
    int X,C,S,D;
} ;

struct xy
{
    int x,y,cost;
} ;

typedef struct ICompare
{
    bool operator() (const stalp a,const stalp b)
    {
        return a.X < b.X;
    }
} Compare;

typedef struct ICompare2
{
    bool operator() (const xy a,const xy b)
    {
        if(a.y == b.y)
            return a.x < b.x;
        return a.y < b.y;
    }
} Compare2;

#define MaxN 100100
#define INF (1000000007)
#define ll long long
#define fs (poz<<1)
#define fd ((poz<<1)+1)
#define tata (poz>>1)
#define MaxAINT (4*MaxN)
#define mij ((li+ls)>>1)
#define INFLL (10000000000LL*100000)

int N;
stalp A[MaxN];
xy segm[MaxN];
ll AINT[MaxAINT];

void citire(void)
{
    f >> N;
    for(int i=1;i<=N;i++)
        f >> A[i].X >> A[i].C >> A[i].S >> A[i].D;
}

inline int cautBinStanga(int li,int ls,int a)
{
    if(li > ls)
        return li;

    if(A[(li+ls)>>1].X == a)
        return ((li+ls)>>1);

    if(A[(li+ls)>>1].X > a)
        return cautBinStanga(li,((li+ls)>>1)-1,a);
    else
        return cautBinStanga(((li+ls)>>1)+1,ls,a);
}

inline int cautBinDreapta(int li,int ls,int a)
{
    if(li > ls)
        return ls;

    if(A[(li+ls)>>1].X == a)
        return ((li+ls)>>1);

    if(A[(li+ls)>>1].X > a)
        return cautBinDreapta(li,((li+ls)>>1)-1,a);
    else
        return cautBinDreapta(((li+ls)>>1)+1,ls,a);
}

void normalizare(void)
{
    A[0].X = 0; A[N+1].X = A[N].X+1;

    for(int i=1;i<=N;i++)
    {
        segm[i].x = cautBinStanga(1,i,A[i].X-A[i].S);
        segm[i].y = cautBinDreapta(i,N,A[i].X+A[i].D);
        segm[i].cost = A[i].C;
    }
}

inline void build(int poz,int li,int ls,ll val)
{
    if(li == ls)
    {
        AINT[poz] = val;
        return ;
    }

    build(fs,li,mij,val);
    build(fd,mij+1,ls,val);

    AINT[poz] = min(AINT[fs],AINT[fd]);
}

inline void update(int poz,int li,int ls,int a,ll val)
{
    if(li == ls)
    {
        AINT[poz] = min(AINT[poz],val);
        return ;
    }

    if(li <= a && a <= mij)
        update(fs,li,mij,a,val);
    else
        update(fd,mij+1,ls,a,val);

    AINT[poz] = min(AINT[fs],AINT[fd]);
}

inline ll query(int poz,int li,int ls,int a,int b)
{
    ll Min = INFLL;

    if(a <= li && ls <= b)
        return AINT[poz];

    if(a <= mij)
        Min = query(fs,li,mij,a,b);
    if(mij < b)
        Min = min(Min,query(fd,mij+1,ls,a,b));

    return Min;
}

void Rezolvare(void)
{
    ll Min;

    sort(A+1,A+N+1,ICompare());
    normalizare();

    sort(segm+1,segm+N+1,ICompare2());

    build(1,1,N,INFLL);

    for(int i=1;i<=N;i++)
    {
        if(segm[i].x == 1)
            Min = 0;
        else
            Min = query(1,1,N,segm[i].x-1,segm[i].y);
        update(1,1,N,segm[i].y,Min+segm[i].cost);
    }
}

int main()
{
    citire();
    Rezolvare();

    g << query(1,1,N,N,N) << "\n";
}