Cod sursa(job #319364)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 31 mai 2009 16:39:53
Problema Stalpi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.42 kb
#include<stdio.h>    
#include<utility>   
#include<algorithm>   
#include<vector>   
#define s second.first   
#define d first   
#define c second.second   
#define DV 140000   
using namespace std;   
pair<int, pair <int,long long> > b[DV];   
vector<long long> arb[20];   
int n,i,j,x[DV],NIV;   
long long INF=1,sol,cmin(int niv,int nod,int st,int dr);   
void readd(),solve(),remake_sd(),build_arb(),upd(int i,long long val);   
int main()      
{      
    readd();      
    solve();      
    return 0;      
}      
void readd()      
{   int ss,dd;long long cc;   
    freopen("stalpi.in","r",stdin);      
    freopen("stalpi.out","w",stdout);    
    scanf("%d",&n);      
    for(i=1;i<=n;i++)      
    {   
        scanf("%d%lld%d%d",&x[i],&cc,&ss,&dd);   
        b[i].d=dd;b[i].s=ss;b[i].c=cc;   
        b[i].s=x[i]-b[i].s;b[i].d=x[i]+b[i].d;INF+=b[i].c;   
    }   
       
}      
void solve()      
{   
    long long CC,CP;   
    sort(x+1,x+n+1);   
    remake_sd();   
    sort(b+1,b+n+1);   
    build_arb();   
    upd(0,0);j=1;   
    for(i=1;i<=n;i++)   
    {   
        CP=INF;   
        while(b[j].d==i)   
        {   
            CC=cmin(NIV,0,b[j].s-1,i-1);   
            CC+=b[j++].c;   
            CP=(CC<CP)?CC:CP;   
        }   
        if(CP<arb[0][i])upd(i,CP);   
    }   
    sol=arb[0][n];   
    printf("%lld\n",sol);   
       
}   
void remake_sd()   
{   
    pair<int*,int*>poz;   
    for(i=1;i<=n;i++)   
    {   
        b[i].s=lower_bound(x+1,x+n+1,b[i].s)-x;   
        b[i].d=upper_bound(x+1,x+n+1,b[i].d)-x-1;   
    }   
}   
void build_arb()   
{   
    int I,J,K;   
    for(NIV=0;(1<<NIV)<n+1;NIV++);NIV++;   
    for(I=0,J=(1<<NIV);I<=NIV;I++,J>>=1)   
        for(K=0;K<J;K++)arb[I].push_back(INF);   
}   
void upd(int I,long long V)   
{   
    int niv,nod;   
    for(niv=0,nod=I;niv<=NIV;niv++,nod>>=1)   
    {   
        if(arb[niv][nod]<=V)return;   
        arb[niv][nod]=V;   
    }   
}   
long long cmin(int niv,int nod,int st,int dr)   
{   
    int S,D,M;S=(nod<<niv);D=S+((1<<niv)-1);   
    long long c1,c2;   
    if(st<=S&&D<=dr)return arb[niv][nod];   
    M=(S+D+1)>>1;   
    if(dr<M){c1=cmin(niv-1,nod<<1,st,dr); return c1;}   
    if(st>=M){c2=cmin(niv-1,(nod<<1)|1,st,dr); return c2;}   
    c1=cmin(niv-1,nod<<1,st,dr);   
    c2=cmin(niv-1,(nod<<1)|1,st,dr);   
    return c1<c2?c1:c2;   
}