Cod sursa(job #3257696)

Utilizator MegaCoderMinoiu Teodor Mihai MegaCoder Data 18 noiembrie 2024 22:18:29
Problema Stalpi Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.05 kb
#include<fstream>
#include<algorithm>
#include<vector>
#include<queue>
#include<climits>
#define ll long long
#define INF LONG_LONG_MAX
std::ifstream fin("stalpi.in");
std::ofstream fout("stalpi.out");
struct interval{
    int x, st, dr, cost;
};
std::vector<interval>v;
int n;
inline int findLeft(int i)
{
    int st=v[i].st;
    int aux=1;
    for(; aux<n; aux<<=1);
    int pos=n;
    for(int d=aux; d; d>>=1)
        if(pos-d>0 && v[pos-d].x>=st)
            pos-=d;
    return pos;
}
inline int findRight(int i)
{
    int dr=v[i].dr;
    int aux=1;
    for(; aux<n; aux<<=1);
    int pos=0;
    for(int d=aux; d; d>>=1)
        if(pos+d<=n && v[pos+d].x<=dr)
            pos+=d;
    return pos;
}
void read()
{
    fin>>n;
    v.resize(n+1);
    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;
    }
    std::sort(v.begin()+1, v.end(), [&](interval x, interval y){
        return x.x<y.x;
    });
    for(int i=1; i<=n; ++i)
    {
        v[i].st=findLeft(i);
        v[i].dr=findRight(i);
    }
    std::sort(v.begin()+1, v.end(), [&](interval x, interval y)
    {
        return x.dr<y.dr;
    });
}

std::deque<ll>min_val, min_ind;
std::vector<ll>dp;
inline ll search_min(int lim)//first min with a pos>=lim
{
    int aux=1;
    for(; aux<(int)min_ind.size(); aux<<=1);
    int pos=(int)min_ind.size()-1;
    for(int d=aux; d; d>>=1)
    {
        if(pos-d>=0 && min_ind[pos-d]>=lim)
            pos-=d;
    }
    return dp[min_ind[pos]];
}
void solve()
{
    dp=std::vector<ll>(n+1, INF);
    dp[0]=0;
    min_val.push_back(0);
    min_ind.push_back(0);
    for(int i=1; i<=n; ++i)
    {
        ll cand_min=search_min(v[i].st-1);
        dp[v[i].dr]=std::min(dp[v[i].dr], cand_min+v[i].cost);
        while(!min_val.empty() && dp[v[i].dr]<min_val.back())
        {
            min_val.pop_back();
            min_ind.pop_back();
        }
        min_val.push_back(dp[v[i].dr]);
        min_ind.push_back(v[i].dr);
    }
    fout<<dp[n];
}
int main()
{
    read();
    solve();
    return 0;
}