Cod sursa(job #1876726)

Utilizator LucianTLucian Trepteanu LucianT Data 12 februarie 2017 16:27:33
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include <bits/stdc++.h>
#define maxN 100005
#define lsb(x) ((x)&(-x))
using namespace std;
const int INF=0x3f3f3f3f;
class InParser
{
public:
    InParser(){}
    InParser(const char *file_name){
        input_file=fopen(file_name,"r");
        cursor=0;
        fread(buffer,SIZE,1,input_file);
    }
    inline InParser &operator>>(int &n)
    {
        while(buffer[cursor]<'0'||buffer[cursor]>'9')
            advance();
        n=0;
        while('0'<=buffer[cursor]&&buffer[cursor]<='9'){
            n=n*10+(buffer[cursor]-'0');
            advance();
        }
        return *this;
    }
private:
    FILE *input_file;
    static const int SIZE=1<<17;
    int cursor;
    char buffer[SIZE];
    inline void advance()
    {
        cursor++;
        if(cursor==SIZE){
            cursor=0;
            fread(buffer,SIZE,1,input_file);
        }
    }
};
struct nod
{
    int cost,st,dr;
}v[maxN];
int n,i,j,x[maxN];
int aib[maxN]; /* aib-like dp */
bool cmp(const nod &a,const nod &b)
{
    return a.dr<b.dr;
}
void update(int pos,int val) /* minimum on left */
{
    for(int i=pos;i>0;i-=lsb(i))
        aib[i]=min(aib[i],val);
}
int query(int pos) /* query on right */
{
    int res=INF;
    for(int i=pos;i<=n;i+=lsb(i))
        res=min(res,aib[i]);
    return res;
}
int main()
{
    InParser f("stalpi.in");
    freopen("stalpi.out","w",stdout);
    f>>n;
    for(i=1;i<=n;i++)
    {
        f>>x[i]>>v[i].cost>>v[i].st>>v[i].dr;
        v[i].st=x[i]-v[i].st;
        v[i].dr=x[i]+v[i].dr;
    }
    sort(x+1,x+n+1);
    sort(v+1,v+n+1,cmp); /* order of processing */
    memset(aib,INF,sizeof(aib));
    for(i=1;i<=n;i++)
    {
        int idx_left=lower_bound(x+1,x+n+1,v[i].st)-x-1;
        int val=0;
        if(idx_left)
            val=query(idx_left);
        val+=v[i].cost;
        int idx_right=upper_bound(x+1,x+n+1,v[i].dr)-x-1;
        update(idx_right,val); /* dp[idx_right]=min(dp[idx_left...n])+cost[i]*/
    }
    printf("%d",aib[n]);
    return 0;
}