Cod sursa(job #249214)

Utilizator vlad_popaVlad Popa vlad_popa Data 27 ianuarie 2009 21:15:23
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.4 kb
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define MAXN 100005
#define MAXA (1<<18)
#define mp make_pair
#define x first.second
#define y first.first
#define cost second
#define ll long long
#define INF 0x3f3f3f3f3f3f3f3fLL

int N;
int C[MAXN], S[MAXN], D[MAXN], sir[MAXN];
pair < pair <int, int>, int > p[MAXN];
ll d[MAXN];
ll AI[MAXA];
ll sol;

void read () {
    scanf ("%d", &N);
    
    for (int i = 1; i <= N; ++ i) {
        scanf (" %d %d %d %d", sir + i, C + i, S + i, D + i);
        S[i] = sir[i] - S[i];
        D[i] = sir[i] + D[i];
    }
}

#define mj ((st + dr) >> 1)

void bin_search (int i) {
    int st = 1, dr = N;
    p[i] = mp (mp (0, N + 1), C[i]);
    
    while (st <= dr) 
        if (sir[mj] >= S[i]) {
            p[i].x = mj;
            dr = mj - 1;
        }
        else
            st = mj + 1;
            
    st = 1; dr = N;
    while (st <= dr) 
        if (sir[mj] <= D[i]) {
            p[i].y = mj;
            st = mj + 1;
        }
        else
            dr = mj - 1;
            
}

#define ns (nod << 1)
#define nd (ns + 1)

void update (int nod, int st, int dr, int poz) {
    if (st >= dr) AI[nod] = d[poz];
    else {
        if (mj >= poz) update (ns, st, mj, poz);
        else update (nd, mj + 1, dr, poz);
        
        AI[nod] = min (AI[ns], AI[nd]);
    }
}

void query (int nod, int st, int dr, int a, int b) {
    if (a <= st && dr <= b) sol = min (sol, AI[nod]);
    else {
        if (mj >= a) query (ns, st, mj, a, b);
        if (mj < b) query (nd, mj + 1, dr, a, b);
    }
}

void solve () {
    sort (sir + 1, sir + N + 1);
    
    for (int i = 1; i <= N; ++ i) bin_search (i);
    sort (p + 1, p + N + 1);
    
    memset (d, 0x3f, sizeof (d));
    memset (AI, 0x3f, sizeof (AI));
    
    for (int i = 1; i <= N; ++ i) 
        if (p[i].x == 1) {
            d[p[i].y] = min (d[p[i].y], (ll)p[i].cost);
            update (1, 1, N, p[i].y);
        }
        else {
            sol = INF;
            query (1, 1, N, p[i].x - 1, p[i].y - 1);
            d[p[i].y] = min (d[p[i].y], sol + p[i].cost); 
            update (1, 1, N, p[i].y);
        }
        
    printf ("%lld\n", d[N]);
}

int main () {
    freopen ("stalpi.in", "r", stdin);
    freopen ("stalpi.out", "w", stdout);
    
    read ();
    solve ();
    
    return 0;
}