Cod sursa(job #3275673)

Utilizator MegaCoderMinoiu Teodor Mihai MegaCoder Data 11 februarie 2025 14:40:56
Problema Stalpi Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.1 kb
#include<fstream>
#include<vector>
#include<algorithm>
#define INF 999999999
#define ll long long
std::ifstream fin("stalpi.in");
std::ofstream fout("stalpi.out");
const int NMAX=100005;
struct point{
    int pos, cost, l, r;
};
std::vector<point>v;
std::vector<ll>dp(4*NMAX, INF);
int n;
inline int getLeft(int pos)
{
    int lg;
    for(lg=1; lg<n; lg<<=1);
    int x=n;
    for(int d=lg; d; d>>=1)
    {
        if(x-d>0 && v[x-d].pos>=pos)
            x-=d;
    }
    return x;
}
inline int getRight(int pos)
{
    int lg;
    for(lg=1; lg<n; lg<<=1);
    int x=0;
    for(int d=lg; d; d>>=1)
    {
        if(x+d<=n && v[x+d].pos<=pos)
            x+=d;
    }
    return x;
}
void read()
{
    fin>>n;
    v.push_back({0, 0, 0, 0});
    for(int i=0; i<n; ++i)
    {
        int d, cost, l, r;
        fin>>d>>cost>>l>>r;
        v.push_back({d, cost, l, r});
    }
    std::sort(v.begin()+1, v.end(), [&](point a, point b){
        return a.pos<b.pos;
    });
    for(int i=1; i<=n; ++i)
    {
        int l=v[i].pos-v[i].l;
        int r=v[i].pos+v[i].r;

        v[i].l= getLeft(l);
        v[i].r= getRight(r);
    }
    std::sort(v.begin()+1, v.end(), [&](point a, point b){
        return a.r<b.r;
    });
}
void update(int st, int dr, int pos, int target, ll val)
{
    if(st==dr)
    {
        dp[pos]=std::min(dp[pos], val);
        return;
    }
    int mid=st+(dr-st)/2;
    if(target<=mid)
        update(st, mid, 2*pos, target, val);
    else
        update(mid+1, dr, 2*pos+1, target, val);
    dp[pos]=std::min(dp[2*pos], dp[2*pos+1]);
}
ll query(int rs, int re, int st, int dr, int pos)
{
    if(re<st || rs>dr)
        return INF;
    if(rs<=st && dr<=re)
        return dp[pos];
    int mid=st+(dr-st)/2;
    ll l=query(rs, re, st, mid, 2*pos);
    ll r=query(rs, re, mid+1, dr, 2*pos+1);
    return std::min(l, r);
}
void buildDP()
{
    update(0, n, 1, 0, 0);//dp[0]=0;
    for(int i=1; i<=n; ++i)
    {
        int st=v[i].l, dr=v[i].r;
        ll tmp=v[i].cost+query(st-1, dr-1, 0, n, 1);
        update(0, n, 1, dr, tmp);
    }
    fout<<query(n, n, 0, n, 1);//dp[n]
}
int main()
{
    read();
    buildDP();
    return 0;
}