Cod sursa(job #319357)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 31 mai 2009 16:32:34
Problema Stalpi Scor 40
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <stdio.h>   
#include <algorithm>   
#include <vector>   
  
#define min(i,j) ((i) > (j) ? (j) : (i))   
#define nmax 100005   
#define arbmax 400005   
  
using namespace std;   
typedef pair<int, int> ii;   
typedef pair<ii, int> iii;   
typedef pair<ii, ii> iiii;   
  
int n, nx, ny, l, r, first, last, caut;   
long long c[nmax], minim;   
long long arb[arbmax], inf;   
iiii a[nmax];   
vector <iii> v;   
  
long long query(int nod, int first, int last, int s1, int s2)   
{   
    if(s1 <= first && last <= s2) return arb[nod];   
    else  
    {   
        int mid = (first + last ) / 2;   
        long long rez = inf;   
        if(s1 <= mid) rez = min(rez, query(nod * 2, first, mid, s1, s2));   
        if(s2 > mid) rez = min(rez, query(nod * 2 + 1, mid + 1, last, s1, s2));   
        return rez;   
    }   
}   
  
void update(int nod, int first, int last, int s1)   
{   
    if(first == last) arb[nod] = c[first];   
    else  
    {   
        int mid = (first + last) / 2;   
        if(s1 <= mid) update(nod * 2, first, mid, s1);   
        else update(nod * 2 + 1, mid + 1, last, s1);   
        arb[nod] = min(arb[nod * 2], arb[nod * 2 + 1]);   
    }   
}   
  
void init(int nod, int first, int last)   
{   
    if(first == last) arb[nod] = c[first];   
    else  
    {   
        int mid = (first + last) / 2;   
        init(nod * 2, first, mid);   
        init(nod * 2 + 1, mid + 1, last);   
        arb[nod] = min(arb[nod * 2], arb[nod * 2 + 1]);   
    }   
}   
  
int main()   
{   
    freopen("stalpi.in", "r", stdin);   
    freopen("stalpi.out", "w", stdout);   
  
    scanf("%d", &n);   
    for(int i = 1; i <= n; i++) scanf("%d%d%d%d", &a[i].first.first, &a[i].first.second, &a[i].second.first, &a[i].second.second);   
  
    sort(a + 1, a + n + 1);   
  
    for(int i = 1; i <= n; i++)   
    {   
        nx = 1, first = 1, last = n, caut = a[i].first.first - a[i].second.first;   
        while(first <= last)   
        {   
            int mid = (first + last) / 2;   
            if(a[mid].first.first >= caut) nx = mid, last = mid - 1;   
            else first = mid + 1;   
        }   
  
        ny = n, first = 1, last = n, caut = a[i].first.first + a[i].second.second;   
        while(first <= last)   
        {   
            int mid = (first + last) / 2;   
            if(a[mid].first.first <= caut) ny = mid, first = mid + 1;   
            else last = mid - 1;   
        }   
  
        v.push_back(iii(ii(nx + 1, ny + 1), a[i].first.second));   
    }   
    sort(v.begin(), v.end());    
  
    inf = 1 << 20; inf *= inf;   
    for(int i = 0; i <= n + 2; i++) c[i] = inf;   
  
    init(1, 1, n + 1);   
    c[1] = 0;   
    update(1, 1, n + 1, 1);   
    for(int i = 0; i < (int)v.size(); i++)   
    {   
        minim = query(1, 1, n + 1, v[i].first.first - 1, n + 1);   
        c[v[i].first.second] = min(c[v[i].first.second], minim + v[i].second);   
        update(1, 1, n + 1, v[i].first.second);   
    }   
    printf("%Ld\n", c[n + 1]);   
  
    return 0;   
}