Cod sursa(job #2447536)

Utilizator NicolaalexandraNicola Alexandra Mihaela Nicolaalexandra Data 13 august 2019 16:05:41
Problema Stalpi Scor 40
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.49 kb
#include <fstream>
#include <algorithm>
#define DIM 100010
#define INF 2000000000
using namespace std;

ifstream fin ("stalpi.in");
ofstream fout ("stalpi.out");
struct stalp{
    int x,cost,st,dr;
};
stalp v[DIM];
int aint[4*DIM],a[DIM],dp[DIM];
int n,s,d,i,Left,Right,mini;
void update (int nod, int st, int dr, int poz, int val){
    if (st == dr){
        aint[nod] = val;
        return;
    }
    int mid = (st+dr)>>1;
    if (poz <= mid)
        update (nod<<1,st,mid,poz,val);
    else update ((nod<<1)|1,mid+1,dr,poz,val);
    aint[nod] = min (aint[nod<<1],aint[(nod<<1)|1]);
}
void query (int nod, int st, int dr, int x, int y){
    if (x <= st && dr <= y){
        mini = min (mini,aint[nod]);
        return;
    }
    int mid = (st+dr)>>1;
    if (x <= mid)
        query (nod<<1,st,mid,x,y);
    if (y > mid)
        query ((nod<<1)|1,mid+1,dr,x,y);
}
inline int cmp (stalp a, stalp b){
    return a.dr < b.dr;
}
int main (){

    fin>>n;
    for (i=1;i<=n;i++){
        fin>>v[i].x>>v[i].cost>>s>>d;
        v[i].st = v[i].x-s;
        v[i].dr = v[i].x+d;
        a[i] = v[i].x;
    }
    /// dp[i] - costul minim sa rezolv primele i puncte
    for (i=1;i<=4*n;i++)
        dp[i] = aint[i] = INF;
    /// sortez dupa X ca sa pot sa determin intervalul compact de puncte incluse intr un interval
    sort (a+1,a+n+1);
    /// sortez intervelele crecator dupa capatul din dreapta (r1<=r2<=..<=rn)
    sort (v+1,v+n+1,cmp);
    for (i=1;i<=n;i++){
        /// vreau sa determin intervalul de puncte care sunt incluse in intervalul farului curent
        int st = 1, dr = n;
        while (st <= dr){
            int mid = (st+dr)>>1;
            if (a[mid] >= v[i].st)
                dr = mid-1;
            else st = mid+1;
        }
        Left = dr;
        st = 1, dr = n;
        while (st <= dr){
            int mid = (st+dr)>>1;
            if (a[mid] <= v[i].dr){
                st = mid+1;
                Right = mid;
            } else dr = mid-1;
        }

        if (Left == 0){ /// e suficientsa aprind doar becul i
            if (v[i].cost < dp[Right]){
                dp[Right] = v[i].cost;
                update (1,1,n,Right,v[i].cost);
            }}

        mini = INF;
        query (1,1,n,Left,n); /// care e minimul pe intervalul Left...n
        int val = mini + v[i].cost;
        if (val < dp[Right]){
            dp[Right] = val;
            update (1,1,n,Right,val);
        }}
    fout<<dp[n];


    return 0;
}