Cod sursa(job #291009)

Utilizator GavrilaVladGavrila Vlad GavrilaVlad Data 29 martie 2009 11:15:52
Problema Stalpi Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.59 kb
#include <stdio.h>
#include <algorithm>
#include <string.h>

#define maxn 100010
#define INF 2000000001

using namespace std;

struct stalp
{
    long x, st, dr, cost;
};

long n, i, j, k, left, right, p1, p2, sol[maxn], best[maxn];
stalp v[maxn], s[maxn];
long ait[6*maxn];

inline long min(long a, long b)
{
    if(a<b) return a;
    return b;
}
inline long max(long a, long b)
{
    if(a>b) return a;
    return b;
}

inline int cmp1(stalp a, stalp b)
{
    if(a.dr < b.dr) return 1;
    return 0;
}

inline int cmp2(stalp a, stalp b)
{
    if(a.x<b.x) return 1;
    return 0;
}

long bs1(long val)
{
    long l, r, m, sol;
    l=0;
    r=n;
    while(l<=r)
    {
        m=(l+r)/2;
        if(s[m].x<val) 
        {
            sol=m;
            l=m+1;
        }
        else r=m-1;
    }
    return sol;
}

long bs2(long val)
{
    long l, r, m, sol;
    l=0;
    r=n;
    while(l<=r)
    {
        m=(l+r)/2;
        if(s[m].x<=val) 
        {
            sol=m;
            l=m+1;
        }        
        else r=m-1;
    }
    return sol;
}

long querry(long nod, long left, long right, long l, long r)
{
    long m=(left+right)/2;
    long rez;
    if(l<=left && right<=r)
    {
        return ait[nod];
    }
    rez=INF;
    if(l<=m) rez=min(rez, querry(2*nod, left, m, l, r));
    if(m<r) rez=min(rez, querry(2*nod+1, m+1, right, l, r));
 //   printf("%d %d %d\n", rez, left, right);
    return rez;
}

void update(long nod, long left, long right, long poz, long val)
{
    long m=(left+right)/2;
    if(left==right)
    {
        ait[nod]=val;
        return;
    }
    if(poz<=m) update(2*nod, left, m, poz, val);
    if(m<poz) update(2*nod+1, m+1, right, poz, val);
    ait[nod]=min(ait[nod*2], ait[nod*2+1]);
}

int main()
{
    freopen("stalpi.in", "r", stdin);
    freopen("stalpi.out", "w", stdout);
    scanf("%d", &n);
    s[0].x=-INF;
    s[0].cost=0;
    s[0].st=s[0].dr=0;
    for(i=1; i<=n; i++)
    {
        scanf("%d %d %d %d", &v[i].x, &v[i].cost, &v[i].st, &v[i].dr);
        s[i]=v[i];
        v[i].st=v[i].x-v[i].st;
        v[i].dr=v[i].x+v[i].dr;
    }
    sort(v+1, v+n+1, cmp1);
    sort(s, s+n+1, cmp2);
    memset(ait, INF, sizeof(ait));
    memset(best, INF, sizeof(best));
    update(1, 0, n, 0, 0);
    best[0]=0;
    for(i=1; i<=n; i++)
    {
        left=bs1(v[i].st);
        right=bs2(v[i].dr);
        best[right]=min(best[right], querry(1, 0, n, left, n)+v[i].cost);
        update(1, 0, n, right, best[right]);
    }
    printf("%d\n", best[n]);
    return 0;
}