Cod sursa(job #2971058)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 26 ianuarie 2023 13:03:06
Problema Stalpi Scor 0
Compilator cpp-64 Status done
Runda sa_fac_schema Marime 3.87 kb
#include <bits/stdc++.h>

using namespace std;

ifstream fin  ("stalpi.in");
ofstream fout ("stalpi.out");

const long long INF = LONG_MAX;
const int MAX_N = 100000;
int n, l, m, r, save, bucket, aux;
struct stalp{
    int st, dr, cost, x;

    inline bool operator < (const stalp &rhs) const{
        return x < rhs.x;
    }
} v[MAX_N + 5];

inline bool cmp(const stalp &s1, const stalp &s2){
    return s1.st < s2.st;
}

long long dp[MAX_N + 5];

struct SEGTREE{
    long long aint[4 * (MAX_N+1) + 5], lazy[4 * (MAX_N+1) + 5];

    inline void build(int nod=1, int st=0, int dr=n){
        lazy[nod] = -1;
        if(st == dr){
            if(st == 0)
                aint[nod] = 0;
            else
                aint[nod] = INF;
        }else{
            int md = ((st + dr) >> 1);
            build(2*nod  , st  , md);
            build(2*nod+1, md+1, dr);
            aint[nod] = min(aint[2*nod], aint[2*nod+1]);
        }
    }

    inline void propag(int nod, int st, int dr){
        if(lazy[nod] != -1){
            aint[nod] = min(aint[nod], lazy[nod]);
            if(st != dr)
                lazy[2*nod] = lazy[2*nod+1] = lazy[nod];
            lazy[nod] = -1;
        }
        return;
    }

    inline void update(int ust, int udr, long long val, int nod=1, int st=0, int dr=n){

        propag(nod, st, dr);

        if(udr < st || dr < ust)
            return;

        if(ust <= st && dr <= udr){
            lazy[nod] = val;
            propag(nod, st, dr);
            return;
        }else{
            int md = ((st + dr) >> 1);
            update(ust, udr, val, 2*nod  , st  , md);
            update(ust, udr, val, 2*nod+1, md+1, dr);

            propag(2*nod  , st  , md);
            propag(2*nod+1, md+1, dr);
            aint[nod] = min(aint[2*nod], aint[2*nod+1]);
        }
    }

    inline int query(int poz, int nod=1, int st=0, int dr=n){

        propag(nod, st, dr);

        if(st == dr){
            return aint[nod];
        }else{
            int md = ((st + dr) >> 1);
            propag(2*nod  , st  , md);
            propag(2*nod+1, md+1, dr);

            if(poz <= md)
                return query(poz, 2*nod  , st  , md);
            else
                return query(poz, 2*nod+1, md+1, dr);
        }
    }
} tree;

int main (){
    ios_base::sync_with_stdio(false);
    fin.tie(nullptr), fout.tie(nullptr);

    fin>>n;
    for(int i=1; i<=n; i++){
        fin>>v[i].x>>v[i].cost>>v[i].st>>v[i].dr;
        v[i].st = v[i].x - v[i].st;
        v[i].dr = v[i].x + v[i].dr;
    }
    sort(v+1, v+n+1);

    for(int i=1; i<=n; i++){
        l = 1;
        save = r = i;
        while(l <= r){
            m = ((l + r) >> 1);
            if(v[i].st <= v[m].x){
                save = m;
                r = m - 1;
            }else
                l = m + 1;
        }
        v[i].st = save;

        save = l = i;
        r = n;
        while(l <= r){
            m = ((l + r) >> 1);
            if(v[m].x <= v[i].dr){
                save = m;
                l = m + 1;
            }else
                r = m - 1;
        }
        v[i].dr = save;
    }
    sort(v+1, v+n+1, cmp);

    ///for(int i=1; i<=n; i++)
    ///    dp[i] = INF;
    ///dp[0] = 0;
    ///for(int i=1; i<=n; i++)
        ///for(int j=v[i].st; j<=v[i].dr; j++)
            ///dp[j] = min(dp[j], dp[v[i].st-1] + v[i].cost);
    ///fout<<dp[n];

    tree.build();
    bucket = (int)log2(n);
    for(int i=1, newval; i<=n; i++){

        for(int j=1; j<=n; j+=bucket)
            aux = tree.query(j);

        newval = tree.query(v[i].st-1) + v[i].cost;

        tree.update(v[i].st, v[i].dr, newval);

        //for(int j=0; j<=n; j++)
        //    cout<<tree.query(j)<<"\n";
        //cout<<"\n";
    }
    fout<<tree.query(n);
    return 0;
}
/**
3 10
3 5
1 3
2 3
**/