Cod sursa(job #289063)

Utilizator savimSerban Andrei Stan savim Data 26 martie 2009 13:12:21
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <stdio.h>
#include <algorithm>
#include <string.h>

using namespace std;

#define MAX_N 131072

struct stalp {
    int X;
    int C;
    int S;
    int D;
} v[MAX_N], A[MAX_N];
int n, p2, sol;
int Arb[4 * MAX_N];

char s[50];

void cit() {
    freopen("stalpi.in", "r", stdin);
    freopen("stalpi.out", "w", stdout);

    scanf("%d\n", &n);
    for (int i = 1; i <= n; i++) {

        fgets(s, 50, stdin);
        int j = 0;
        while (s[j] != ' ') {
            v[i].X = v[i].X * 10 + s[j] - '0';
            j++;
        }
        j++;

        while (s[j] != ' ') {
            v[i].C = v[i].C * 10 + s[j] - '0';
            j++;
        }
        j++;

        while (s[j] != ' ') {
            v[i].S = v[i].S * 10 + s[j] - '0';
            j++;
        }
        j++;

        while ('0' <= s[j] && s[j] <= '9') {
            v[i].D = v[i].D * 10 + s[j] - '0';
            j++;
        }
        
        A[i] = v[i];
    }
}

inline int cmp(stalp A, stalp B) {
    return A.X < B.X;
}

inline int cmp2(stalp P, stalp Q) {
    return P.X - P.S < Q.X - Q.S;
}

inline int bin(int poz) {
    if (poz < 0) poz = 0;

    int st = 0, dr = n + 1, mid = 0, sol = 0;

    while (st + 1 < dr) {
        mid = (st + dr) >> 1;

        if (v[mid].X > poz) dr = mid;
        else if (v[mid].X <= poz) {
                sol = mid;
                st = mid;
             }
    }

    return sol;
}

int query(int nod) {
    if (nod < p2) return 0;

    int ret = 2147000000;

    while (nod) {
        if (Arb[nod] < ret && Arb[nod]) ret = Arb[nod];
        nod >>= 1;
    }

    return ret;
}

void update(int nod, int st, int dr, int p, int q, int cost) {
    if (st > q || dr < p) return;

    if (p <= st && dr <= q) {
        if (Arb[nod] > cost || Arb[nod] == 0) Arb[nod] = cost;
    }
    else {
        update(nod << 1, st, (st + dr) >> 1, p, q, cost);
        update((nod << 1) + 1, ((st + dr) >> 1) + 1, dr, p, q, cost);
    }
}

void solve() {
    sort(v + 1, v + n + 1, cmp);
    sort(A + 1, A + n + 1, cmp2);

    p2 = 1;
    while (p2 < n) p2 *= 2;

    for (int i = 1; i <= n; i++) {
        int st = bin(A[i].X - A[i].S - 1);
        int dr = bin(A[i].X + A[i].D);

        int cost = query(p2 + st - 1);
        update(1, 1, p2, st, dr, cost + A[i].C);
    }

    sol = query(p2 + n - 1);
    printf("%d\n", sol);
}

int main() {

    cit();
    solve();

    return 0;
}