Cod sursa(job #137287)

Utilizator mariusdrgdragus marius mariusdrg Data 17 februarie 2008 10:57:53
Problema Stalpi Scor 60
Compilator cpp Status done
Runda preONI 2008, Runda 4, Clasa a 10-a Marime 2.2 kb
#include<stdio.h>
#include<vector>
#include<algorithm>
#define mkp make_pair
#define pb push_back
#define ff first
#define ss second
#define LL long long
using namespace std;
const int maxn = 102000;

vector < pair < pair <int,int>,int > > vect;
int pct[maxn];
long long ar[maxn * 4];
long long d[maxn];
int N,M;
int inc,nodd,nods;
LL min(LL i,LL j){return i < j ? i : j;}

const int inf = 2000000000;
int cautare(int val)
{
        int x = 0,p;
        for(p = 1;p <= N; p <<= 1);
        for(;p;p >>= 1)
                 if (x + p <= N && pct[x + p] <= val) x += p;
        return x;
}

void update(int st,int dr,int nod)
{
        if (st == dr)
        {
                ar[nod] = d[inc];
                return ;
        }
        int mid = (st + dr) / 2;
        if (mid >= inc) update(st,mid,nod * 2);
        if (mid < inc) update(mid + 1,dr,nod * 2 + 1);
        ar[nod] = min(ar[nod * 2],ar[nod * 2 + 1]);
}

LL querry(int st,int dr,int nod)
{
        if (st >= nods && dr <= nodd) return ar[nod];
        int mid = (st + dr) / 2;
        if (mid >= nodd) return querry(st,mid,nod * 2);
        if (mid < nods) return querry(mid + 1,dr,nod * 2 + 1);
        return min(querry(st,mid,nod * 2),querry(mid + 1,dr,nod * 2 + 1));
}

int main()
{
        freopen("stalpi.in","r",stdin);
        freopen("stalpi.out","w",stdout);
        scanf("%d",&N);
     //   printf("%d\n",sizeof(ar) + sizeof(d));
        int i;
        for(i = 1;i <= N; ++i)
        {
                int x,c,st,dr;
                scanf("%d %d %d %d",&x,&c,&st,&dr);
                pct[i] = x;
                vect.pb(mkp(mkp(x - st,x + dr),c) );
                d[i] = (long long)inf * 100;
                inc = i;
                update(0,N,1);
        }
        pct[0] = -inf;
        sort(vect.begin(),vect.end());
        sort(pct + 1,pct + N + 1);
        for(i = 0;i < N; ++i)
        {
                nods = cautare(vect[i].ff.ff);
                if (pct[nods] == vect[i].ff.ff)  nods--;
                nodd = cautare(vect[i].ff.ss);
                nodd--;
                d[nodd + 1] = min(d[nodd + 1],querry(0,N,1) + vect[i].ss);
                inc = nodd + 1;
                update(0,N,1);
        }
        printf("%lld\n",d[N]);
        return 0;
}