Cod sursa(job #3254375)

Utilizator Darius1414Dobre Darius Adrian Darius1414 Data 7 noiembrie 2024 13:38:26
Problema Stalpi Scor 20
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.91 kb
#include <fstream>
#include <iostream>
#include <algorithm>
#define inf 2000000000
#define nmx 100005
using namespace std;
int n;
long long dp[nmx],arb[400001];
struct edge
{
    int st,dr,x;
    long long c;
};
edge v[nmx];
int l,r;
bool cmp(edge a,edge b)
{
    return a.x<=b.x;
}
void build (int index,int st,int dr)
{
    if (st==dr)
    {
        arb[index]=dp[st];
        return;
    }
    int mid=(st+dr)/2;
    build(index*2,st,mid);
    build(index*2+1,mid+1,dr);
    arb[index]=min(arb[index*2],arb[index*2+1]);
}
void update(int index,int st,int dr,int pos,int x)
{
    if (st==dr)
    {
        arb[index]=x;
        return;
    }
    int mid=(st+dr)/2;
    if (st<=pos && pos<=mid)
        update(index*2,st,mid,pos,x);
    else
        update(index*2+1,mid+1,dr,pos,x);
    arb[index]=min(arb[index*2],arb[index*2+1]);
}
long long searc(int index,int st,int dr,int a,int b)
{
    if (dr<a || st>b)
        return inf;
    if (st==dr)
        return arb[index];
    int mid=(st+dr)/2;
    return min(searc(index*2,st,mid,a,b),searc(index*2+1,mid+1,dr,a,b));
}
void show(int index,int st,int dr)
{
    cout<<index<<"   "<<st<<' '<<dr<<"  "<<arb[index]<<'\n';
    if (st==dr) return;
    int mid=(st+dr)/2;
    show(index*2,st,mid);
    show(index*2+1,mid+1,dr);
}
int main()
{
    ifstream f ("stalpi.in");
    ofstream g ("stalpi.out");
    f>>n;
    for (int i=1; i<=n; i++)
    {
        f>>v[i].x>>v[i].c>>l>>r;
        v[i].st=v[i].x-l;
        v[i].dr=v[i].x+r;
    }
    sort (v+1,v+n+1,cmp);
    for (int i=1; i<=n; i++)
        dp[i]=v[i].c+dp[i-1];
    build(1,1,n);
    //for (int i=1; i<=n; i++)
    // cout<<v[i].x<<' ';
    //cout<<'\n';
    for (int i=1; i<=n; i++)
    {
        int st=1,dr=n,mid,sol,sol2;
        while (st<=dr)
        {
            mid=(st+dr)/2;
            if (v[mid].x<v[i].st)
                st=mid+1;
            else
            {
                sol=mid;
                dr=mid-1;
            }
        }
        sol--;
        st=1,dr=n;
        while (st<=dr)
        {
            mid=(st+dr)/2;
            if (v[mid].x>v[i].dr)
                dr=mid-1;
            else
            {
                st=mid+1;
                sol2=mid;
            }
        }
        //cout<<i<<' '<<v[i].x<<' '<<v[i].st<<' '<<v[i].dr<<"   "<<sol<<' '<<sol2<<'\n';
        ///sol->pana unde trb luminat dinainte
        ///sol2->pana unde lumineaza i
        long long cmin;
        if (sol==0) cmin=0;
        else cmin=searc(1,1,n,sol,sol2-1);
        //cout<<sol<<' '<<cmin<<'\n'<<'\n';
        // cout<<cmin<<'\n';
        long long now=cmin+v[i].c;
        // cout<<dp[sol2]<<' ';
        if (now<dp[sol2])
        {
            dp[sol2]=now;
            update(1,1,n,sol2,dp[sol2]);
        }
        //show(1,1,n);
        //cout<<'\n'<<'\n';
        //  cout<<dp[sol2]<<'\n';
    }
    g<<dp[n];
}