Cod sursa(job #2971258)

Utilizator BlueLuca888Girbovan Robert Luca BlueLuca888 Data 26 ianuarie 2023 21:44:40
Problema Stalpi Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.09 kb
#include <bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC target ("popcnt")

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;
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;
}

struct SEGTREE{
    long long aint[MAX_N + 5], lazy_update[4 * MAX_N + 5];
    bitset <4 * MAX_N + 5> lazy;

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

    inline void propag(int nod, int st, int dr){
        if(lazy[nod] == true){
            lazy[nod] = false;

            if(st == dr){
                aint[st] = min(aint[st], lazy_update[nod]);
            }else{
                if(lazy[2*nod] == true)
                    lazy_update[2*nod] = min(lazy_update[2*nod], lazy_update[nod]);
                else{
                    lazy[2*nod] = true;
                    lazy_update[2*nod] = lazy_update[nod];
                }

                if(lazy[2*nod+1] == true)
                    lazy_update[2*nod+1] = min(lazy_update[2*nod+1], lazy_update[nod]);
                else{
                    lazy[2*nod+1] = true;
                    lazy_update[2*nod+1] = lazy_update[nod];
                }
            }
        }
        return;
    }

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

        if(st > dr)
            return;

        propag(nod, st, dr);

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

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

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

        propag(nod, st, dr);

        if(st == dr){
            return aint[st];
        }else{
            int md = ((st + dr) >> 1);
            if(poz <= md)
                return query(poz, 2*nod  , st  , md); ///prima jumatate
            else
                return query(poz, 2*nod+1, md+1, dr); ///a doua jumatate
        }
    }
} tree;

int main (){
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr), cout.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);

    /**
    long long dp[MAX_N + 5];
    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();
    for(int i=1; i<=n; i++){

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

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

    fout<<tree.query(n);
    return 0;
}
/**
4
3 1 3 5
1 10 10 9
7 2 5 3
10 18 4 4
**/