Problem p03182 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define _                                                                      \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define int long long
#define pb push_back
#define sz(i) (int)(i.size())
#define F first
#define S second
#define LL long double
#define P pair<int, int>
#ifdef ONLINE_JUDGE
#define endl '\n'
#endif
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#ifndef ONLINE_JUDGE
#define tr(...)                                                                \
  {                                                                            \
    __l(__LINE__);                                                             \
    __f(#__VA_ARGS__, __VA_ARGS__);                                            \
  }
inline void __l(int line) { cerr << "#" << line << ": "; }
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define tr(...)
#endif
template <class T> void smin(T &a, T val) {
  if (a > val)
    a = val;
}
template <class T> void smax(T &a, T val) {
  if (a < val)
    a = val;
}
template <typename T>
inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
  bool first = true;
  os << "[";
  for (auto i : v) {
    if (!first)
      os << ", ";
    os << i;
    first = false;
  }
  return os << "]";
}
const int N = 2 * (int)1e5 + 10;
// make sure N size is correctttt!!!!!!!!!

// Segment tree operations: Range update(Lazy propagation) and Range Query

const int MAX = 1e5 + 5;
const int LIM = 3e5 + 5; // equals 2 * 2^ceil(log2(n))

int a[MAX];
int seg[LIM];
int lazy[LIM];
bool push[LIM];

// Complexity: O(1)
// Stores what info. segment[i..j] should store
int combine(int &a, int &b) { return max(a, b); }

// Lazy propagation
void propagate(int t, int i, int j) {
  if (push[t]) {
    seg[t] = seg[t] + lazy[t];
    if (i != j) {
      push[t * 2] = true;
      push[t * 2 + 1] = true;
      lazy[t * 2] = lazy[t * 2] + lazy[t];
      lazy[t * 2 + 1] = lazy[t * 2 + 1] + lazy[t];
    }
    push[t] = false;
    lazy[t] = 0;
  }
}

// Complexity: O(n)
void build(int t, int i, int j) {
  push[t] = false;
  lazy[t] = 0;
  if (i == j) {
    // base case : leaf node information to be stored here
    seg[t] = a[i];
    return;
  }
  int mid = (i + j) / 2;
  build(t * 2, i, mid);
  build(t * 2 + 1, mid + 1, j);
  seg[t] = combine(seg[2 * t], seg[2 * t + 1]);
}

// Complexity: O(log n)
void update(int t, int i, int j, int l, int r, int x) {
  propagate(t, i, j);
  if (i > r || j < l) {
    return;
  }
  if (l <= i && j <= r) {
    // base case : leaf node information to be stored here
    lazy[t] += x;
    push[t] = true;
    propagate(t, i, j);
    return;
  }
  int mid = (i + j) / 2;
  update(t * 2, i, mid, l, r, x);
  update(t * 2 + 1, mid + 1, j, l, r, x);
  seg[t] = combine(seg[2 * t], seg[2 * t + 1]);
}

// Complexity: O(log n)
int query(int t, int i, int j, int l, int r) {
  propagate(t, i, j);
  if (i > r || j < l) {
    // base case: result of out-of-bound query
    return 0;
  }
  if (l <= i && j <= r) {
    return seg[t];
  }
  int mid = (i + j) / 2;
  if (l <= mid) {
    if (r <= mid) {
      return query(t * 2, i, mid, l, r);
    } else {
      int a = query(t * 2, i, mid, l, r);
      int b = query(t * 2 + 1, mid + 1, j, l, r);
      return combine(a, b);
    }
  } else {
    return query(t * 2 + 1, mid + 1, j, l, r);
  }
}

int n, m, dp[N];
vector<P> L[N], R[N];

int32_t main() {
  _ cin >> n >> m;

  for (int i = 0; i < m; ++i) {
    int l, r, x;
    cin >> l >> r >> x;
    L[l].pb({l - 1, x});
    R[r].pb({l - 1, x});
  }

  // void update(int t, int i, int j, int l, int r, int x) {
  // int query(int t, int i, int j, int l, int r) {

  int ans = 0;
  for (int i = 1; i <= n; ++i) {
    for (auto it : L[i])
      update(1, 0, n, 0, it.F, it.S);

    int tmp_ans = query(1, 0, n, 0, i - 1);
    smax(ans, tmp_ans);
    update(1, 0, n, i, i, tmp_ans);

    for (auto it : R[i])
      update(1, 0, n, 0, it.F, -it.S);
  }

  cout << ans;
  // make sure N size is correct!!!!!!!!!
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define _                                                                      \
  ios_base::sync_with_stdio(false);                                            \
  cin.tie(NULL);                                                               \
  cout.tie(NULL);
#define int long long
#define pb push_back
#define sz(i) (int)(i.size())
#define F first
#define S second
#define LL long double
#define P pair<int, int>
#ifdef ONLINE_JUDGE
#define endl '\n'
#endif
const int inf = 0x3f3f3f3f3f3f3f3LL;
const int mod = (int)1e9 + 7;
using namespace std;
#ifndef ONLINE_JUDGE
#define tr(...)                                                                \
  {                                                                            \
    __l(__LINE__);                                                             \
    __f(#__VA_ARGS__, __VA_ARGS__);                                            \
  }
inline void __l(int line) { cerr << "#" << line << ": "; }
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define tr(...)
#endif
template <class T> void smin(T &a, T val) {
  if (a > val)
    a = val;
}
template <class T> void smax(T &a, T val) {
  if (a < val)
    a = val;
}
template <typename T>
inline std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
  bool first = true;
  os << "[";
  for (auto i : v) {
    if (!first)
      os << ", ";
    os << i;
    first = false;
  }
  return os << "]";
}
const int N = 2 * (int)1e5 + 10;
// make sure N size is correctttt!!!!!!!!!

// Segment tree operations: Range update(Lazy propagation) and Range Query

const int MAX = 2e5 + 5;
const int LIM = 7.5 * 1e5 + 5; // equals 2 * 2^ceil(log2(n))

int a[MAX];
int seg[LIM];
int lazy[LIM];
bool push[LIM];

// Complexity: O(1)
// Stores what info. segment[i..j] should store
int combine(int &a, int &b) { return max(a, b); }

// Lazy propagation
void propagate(int t, int i, int j) {
  if (push[t]) {
    seg[t] = seg[t] + lazy[t];
    if (i != j) {
      push[t * 2] = true;
      push[t * 2 + 1] = true;
      lazy[t * 2] = lazy[t * 2] + lazy[t];
      lazy[t * 2 + 1] = lazy[t * 2 + 1] + lazy[t];
    }
    push[t] = false;
    lazy[t] = 0;
  }
}

// Complexity: O(n)
void build(int t, int i, int j) {
  push[t] = false;
  lazy[t] = 0;
  if (i == j) {
    // base case : leaf node information to be stored here
    seg[t] = a[i];
    return;
  }
  int mid = (i + j) / 2;
  build(t * 2, i, mid);
  build(t * 2 + 1, mid + 1, j);
  seg[t] = combine(seg[2 * t], seg[2 * t + 1]);
}

// Complexity: O(log n)
void update(int t, int i, int j, int l, int r, int x) {
  propagate(t, i, j);
  if (i > r || j < l) {
    return;
  }
  if (l <= i && j <= r) {
    // base case : leaf node information to be stored here
    lazy[t] += x;
    push[t] = true;
    propagate(t, i, j);
    return;
  }
  int mid = (i + j) / 2;
  update(t * 2, i, mid, l, r, x);
  update(t * 2 + 1, mid + 1, j, l, r, x);
  seg[t] = combine(seg[2 * t], seg[2 * t + 1]);
}

// Complexity: O(log n)
int query(int t, int i, int j, int l, int r) {
  propagate(t, i, j);
  if (i > r || j < l) {
    // base case: result of out-of-bound query
    return 0;
  }
  if (l <= i && j <= r) {
    return seg[t];
  }
  int mid = (i + j) / 2;
  if (l <= mid) {
    if (r <= mid) {
      return query(t * 2, i, mid, l, r);
    } else {
      int a = query(t * 2, i, mid, l, r);
      int b = query(t * 2 + 1, mid + 1, j, l, r);
      return combine(a, b);
    }
  } else {
    return query(t * 2 + 1, mid + 1, j, l, r);
  }
}

int n, m, dp[N];
vector<P> L[N], R[N];

int32_t main() {
  _ cin >> n >> m;

  for (int i = 0; i < m; ++i) {
    int l, r, x;
    cin >> l >> r >> x;
    L[l].pb({l - 1, x});
    R[r].pb({l - 1, x});
  }

  // void update(int t, int i, int j, int l, int r, int x) {
  // int query(int t, int i, int j, int l, int r) {

  int ans = 0;
  for (int i = 1; i <= n; ++i) {
    for (auto it : L[i])
      update(1, 0, n, 0, it.F, it.S);

    int tmp_ans = query(1, 0, n, 0, i - 1);
    smax(ans, tmp_ans);
    update(1, 0, n, i, i, tmp_ans);

    for (auto it : R[i])
      update(1, 0, n, 0, it.F, -it.S);
  }

  cout << ans;
  // make sure N size is correct!!!!!!!!!
  return 0;
}