Cod sursa(job #2971909)

Utilizator YusyBossFares Yusuf YusyBoss Data 28 ianuarie 2023 12:26:28
Problema Stalpi Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.89 kb
#include <bits/stdc++.h>
#define NMAX 100000
#define int64 long long

using namespace std;

struct strstalp {
  int x, s, d, c;
  int lindex, rindex;
};

strstalp v[NMAX + 1];
int64 dp[NMAX + 1];
int64 vlazy[4 * NMAX + 1];

bool cmp(strstalp A, strstalp B) {
  return A.x < B.x;
}

bool cmp1(strstalp A, strstalp B) {
  return A.lindex < B.lindex;
}

int bs_left(int st, int dr, int poz) {
  int mij, sol;

  sol = dr;
  while (st <= dr) {
    mij = (st + dr ) / 2;
    if (v[mij].x >= poz) {
      sol = mij;
      dr = mij - 1;
    }
    else
      st = mij + 1;
  }

  return sol;
}

int bs_right(int st, int dr, int poz) {
  int mij, sol;

  sol = dr;
  while (st <= dr) {
    mij = (st + dr ) / 2;
    if (v[mij].x <= poz) {
      sol = mij;
      st = mij + 1;
    }
    else
      dr = mij - 1;
  }

  return sol;
}

void propagate(int node, int left, int right) {
  if (vlazy[node] != LLONG_MAX) {
    if (left != right) {
      vlazy[node * 2] = min(vlazy[node * 2], vlazy[node]);
      vlazy[node * 2 + 1] = min(vlazy[node * 2 + 1], vlazy[node]);
    }
    else
      dp[left] = min(dp[left], vlazy[node]);
    vlazy[node] = LLONG_MAX;
  }
}

void update(int node, int left, int right, int uleft, int uright, int val) {
  propagate(node, left, right);

  if (uleft == left && uright == right) {
    vlazy[node] = val;
    return;
  }

  int med = (left + right) / 2;

  propagate(node * 2, left, med);
  propagate(node * 2 + 1, med + 1, right);

  if (uleft <= med)
    update(node * 2, left, med, uleft, min(med, uright), val);
  if (uright > med)
    update(node * 2 + 1, med + 1, right, max(uleft, med + 1), uright, val);
}

int query(int node, int left, int right, int poz) {
  propagate(node, left, right);

  if (left == right)
    return dp[poz];

  int med = (left + right) / 2;

  propagate(node * 2, left, med);
  propagate(node * 2 + 1, med + 1, right);

  if (poz <= med)
    return query(node * 2, left, med, poz);
  else
    return query(node * 2 + 1, med + 1, right, poz);
}

signed main() {
  freopen("stalpi.in", "r", stdin);
  freopen("stalpi.out", "w", stdout);

  ios_base::sync_with_stdio(0);
  cin.tie(NULL);
  cout.tie(NULL);

  int n, i, j;
  cin >> n;

  for (i = 1; i <= n; i++) {
    cin >> v[i].x >> v[i].c >> v[i].s >> v[i].d;
  }

  sort(v + 1, v + n + 1, cmp);

  for (i = 1; i <= n; i++) {
    v[i].lindex = bs_left(1, i, v[i].x - v[i].s);
    v[i].rindex = bs_right(i, n, v[i].x + v[i].d);
    dp[i] = LLONG_MAX;
  }

  for (i = 1; i <= 4 * NMAX; i++)
    vlazy[i] = LLONG_MAX;

  sort(v + 1, v + n + 1, cmp1);

  for (i = 1; i <= n; i++) {
    int64 val;
    if (v[i].lindex == 1)
      val = v[i].c;
    else
      val = query(1, 1, n, v[i].lindex - 1) + v[i].c;

    update(1, 1, n, v[i].lindex, v[i].rindex, val);
  }

  cout << query(1, 1, n, n);
  return 0;
}