Cod sursa(job #139119)

Utilizator filipbFilip Cristian Buruiana filipb Data 19 februarie 2008 18:59:19
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include <stdio.h>
#include <algorithm>

using namespace std;

typedef struct { int x, c, st, dr; } stalp;
#define minim(a, b) ((a < b) ? a : b)
#define INF 999999999999999LL
#define PII pair< pair<int, int>, int >
#define f first.first
#define s first.second
#define cost second
#define ll long long
#define NMax 100005
#define AMax 262144

int N, X[NMax];
stalp V[NMax];
ll A[AMax], D[NMax];
PII I[NMax];

int cmp_stalp(const stalp& a, const stalp &b)
{ return a.x < b.x; }

int cmp_pair(const PII& a, const PII& b)
{ return a.s < b.s; }

void update(int n, int l, int r, int poz, ll val)
{
    if (l == r)
        A[n] = minim(A[n], val);
    else
    {
        int m = (l + r) / 2;
        
        if (poz <= m)
            update(2 * n, l, m, poz, val);
        else
            update(2 * n + 1, m+1, r, poz, val);
        A[n] = minim(A[2*n], A[2*n+1]);
    }
}

ll query(int n, int l, int r, int a, int b)
{
    if (a <= l && r <= b)
        return A[n];

    int m = (l + r) / 2;
    ll i1 = INF, i2 = INF;
    
    if (a <= m) i1 = query(2*n, l, m, a, b);
    if (b > m) i2 = query(2*n+1, m+1, r, a, b);

    return minim(i1, i2);
}

int main(void)
{
    int i; ll j;
    
    freopen("stalpi.in", "r", stdin);
    freopen("stalpi.out", "w", stdout);

    scanf("%d", &N);
    for (i = 1; i <= N; i++)
        scanf("%d %d %d %d", &V[i].x, &V[i].c, &V[i].st, &V[i].dr);

    sort(V+1, V+N+1, cmp_stalp);
    for (i = 1; i <= N; i++)
        X[i] = V[i].x;

    for (I[1].f = 1, i = 2; i <= N; i++)
        I[i].f = lower_bound(X+1, X+i, X[i] - V[i].st) - X;
    for (I[N].s = N, i = 1; i < N; i++)
        I[i].s = (upper_bound(X+i+1, X+N+1, X[i] + V[i].dr) - X) - 1;
    for (i = 1; i <= N; i++)
        I[i].cost = V[i].c;

    for (i = 1; i < AMax; i++)
        A[i] = INF;
    for (i = 1; i <= N; i++)
        D[i] = INF;

    sort(I+1, I+N+1, cmp_pair);
        
    update(1, 0, N, 0, 0);
    for (i = 1; i <= N; i++)
    {
        j = query(1, 0, N, I[i].f-1, I[i].s-1) + I[i].cost;
        if (j < D[I[i].s])
        {
            D[I[i].s] = j;
            update(1, 0, N, I[i].s, j);
        }
    }

    printf("%lld\n", D[N]);

    return 0;
}