Cod sursa(job #278011)
#include <fstream>
#include <algorithm>
using namespace std;
#define MAXN 100010
#define MAXX 262144
#define ll long long
#define INF 1000000000000LL
int N, L;
int ileft, iright;
ll value;
int X[MAXN], S[MAXN], D[MAXN], Cost[MAXN];
int Q[MAXN], P[MAXN];
ll C[MAXN], best[MAXX];
int cmp(int i, int j)
{
return X[i] + D[i] < X[j] + D[j];
}
int cmp2(int i, int j)
{
return X[Q[i]] < X[Q[j]];
}
int search(int x)
{
int front = 1, middle, back = N, rez = 0;
while (front <= back)
{
middle = (front + back) / 2;
if (X[Q[middle]] >= x)
{
rez = middle;
back = middle - 1;
}
else front = middle + 1;
}
return rez;
}
int search2(int x)
{
int front = 1, middle, back = N, rez = 0;
while (front <= back)
{
middle = (front + back) / 2;
if (X[P[middle]] + D[P[middle]] >= x)
{
rez = middle;
back = middle - 1;
}
else front = middle + 1;
}
return rez;
}
ll query(int p, int r, int nod)
{
if (ileft <= p && r <= iright) return best[nod];
else {
int q = (p+r) / 2;
ll rez = INF;
if (ileft <= q) rez = query(p, q, nod*2);
if (q < iright) rez = min(rez, query(q+1, r, nod*2+1));
return rez;
}
}
void update(int p, int r, int nod)
{
if (p == r) best[nod] = value;
else {
int q = (p+r) / 2;
if (ileft <= q) update(p, q, nod*2);
if (q < iright) update(q+1, r, nod*2+1);
best[nod] = min(best[nod*2], best[nod*2+1]);
}
}
int main()
{
ifstream fin("stalpi.in");
ofstream fout("stalpi.out");
int i;
fin >> N;
for (i = 1; i <= N; i++)
{
fin >> X[i] >> Cost[i] >> S[i] >> D[i];
P[i] = Q[i] = i;
}
for (L = 1; L < N; L <<= 1);
for (i = 1; i < 2*L; i++) best[i] = INF;
sort(P+1, P+N+1, cmp);
sort(Q+1, Q+N+1, cmp2);
for (i = 1; i <= N; i++)
{
ileft = search(X[P[i]] - S[P[i]]) - 1;
ileft = search2(X[Q[ileft]]);
iright = i-1;
if (ileft == 0) C[i] = Cost[P[i]];
else if (ileft > iright) C[i] = Cost[P[i]];
else C[i] = query(1, L, 1) + Cost[P[i]];
ileft = iright = i;
value = C[i];
update(1, L, 1);
}
ileft = search2(X[P[N]]);
iright = N;
fout << query(1, L, 1);
return 0;
}