Cod sursa(job #1717568)

Utilizator alexpetrescuAlexandru Petrescu alexpetrescu Data 15 iunie 2016 10:58:02
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.99 kb
#include <cstdio>
#include <algorithm>
#define INF 1000000000000000000LL
#define MAXN 100000
struct mycreation{
    int x, c, l, r;
}v[MAXN+1];
int a[MAXN+1], lista[MAXN+1], next[MAXN+1];
long long d[MAXN+1], aint[4*MAXN+1];
int poz, left, right;
long long ans, val;
bool cmp(const mycreation a, const mycreation b){
    return a.x<b.x;
}
inline long long min2(long long a, long long b){
    if(a<b) return a;
    else return b;
}
void update(int p, int st, int dr){
    if(st==dr){
        aint[p]=val;
    }else{
        int m=(st+dr)/2;
        if(poz<=m) update(2*p, st, m);
        else update(2*p+1, m+1, dr);
        aint[p]=min2(aint[2*p], aint[2*p+1]);
    }
}
void query(int p, int st, int dr){
    if((left<=st)&&(dr<=right)){
        ans=min2(ans, aint[p]);
    }else{
        int m=(st+dr)/2;
        if(left<=m) query(2*p, st, m);
        if(m+1<=right) query(2*p+1, m+1, dr);
    }
}
int main(){
    int n, i, rez, pas, p;
    FILE *fin, *fout;
    fin=fopen("stalpi.in", "r");
    fout=fopen("stalpi.out", "w");
    fscanf(fin, "%d", &n);
    for(i=1; i<=n; i++){
        fscanf(fin, "%d%d%d%d", &v[i].x, &v[i].c, &v[i].l, &v[i].r);
    }
    std::sort(v+1, v+n+1, cmp);
    for(i=1; i<=n; i++){
        rez=i;
        for(pas=1<<16; pas; pas>>=1){
            if((rez-pas>0)&&(v[rez-pas].x>=v[i].x-v[i].l)) rez-=pas;
        }
        a[i]=rez;
        rez=i;
        for(pas=1<<16; pas; pas>>=1){
            if((rez+pas<=n)&&(v[rez+pas].x<=v[i].x+v[i].r)) rez+=pas;
        }
        next[i]=lista[rez];
        lista[rez]=i;
    }
    for(i=1; i<=n; i++){
        d[i]=INF;
        p=lista[i];
        while(p){
            left=a[p]-1;
            right=i-1;
            ans=INF;
            query(1, 0, n);
            if(d[i]>ans+v[p].c) d[i]=ans+v[p].c;
            p=next[p];
        }
        poz=i;
        val=d[i];
        update(1, 0, n);
    }
    fprintf(fout, "%lld\n", d[n]);
    fclose(fin);
    fclose(fout);
    return 0;
}