Problem p02971 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#include <iostream>

using namespace std;
#define CIN ios_base::sync_with_stdio(0)
#define mx 100007
#define i64 long long

i64 arr[mx], tree[3 * mx], lazy[3 * mx];

void BuildTree(i64 node, i64 b, i64 e) {
  if (b == e) {
    tree[node] = arr[b];
    return;
  }

  i64 mid = (b + e) / 2;
  i64 left = 2 * node, right = 2 * node + 1;

  BuildTree(left, b, mid);
  BuildTree(right, mid + 1, e);

  tree[node] = max(tree[left], tree[right]);
}

i64 query(i64 node, i64 b, i64 e, i64 l, i64 r) {
  if (b > r || b > e || e < l) {
    return INT_MIN; // return 0 as sum;
  }

  if (lazy[node] != 0) {
    tree[node] += (e - b + 1) * lazy[node];

    if (b != e) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }

  if (b >= l && e <= r) {
    return tree[node];
  }

  i64 mid = (b + e) / 2, left = node * 2, right = node * 2 + 1;
  i64 lft = query(left, b, mid, l, r);
  i64 rgt = query(right, mid + 1, e, l, r);

  return max(lft, rgt);
}

void updateRange(i64 node, i64 b, i64 e, i64 l, i64 r, i64 value) {
  if (lazy[node] != 0) {
    tree[node] += (e - b + 1) * lazy[node];

    if (b != e) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }

  if (b > e || b > r || e < l) {
    // start > end or start > r or end < l ....out of range
    return;
  }

  if (b >= l && e <= r) {
    // fully cover range [l....r]
    tree[node] += (e - b + 1) * value;

    if (b != e) {
      // not a leaf
      lazy[node * 2] += value;
      lazy[node * 2 + 1] += value;
    }
    return; // why ? dud
  }

  i64 mid = (b + e) / 2, left = node * 2, right = node * 2 + 1;

  updateRange(left, b, mid, l, r, value);
  updateRange(right, mid + 1, e, l, r, value);

  tree[node] = max(tree[left], tree[right]);
}

int main() {
  CIN;
  i64 t, qu, q, p, a;
  i64 val;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> arr[i];

  BuildTree(1, 1, n);
  memset(lazy, 0, sizeof lazy);

  for (int i = 1; i <= n; i++) {
    int idx = i;
    updateRange(1, 1, n, idx, idx, -arr[idx]);

    i64 left = query(1, 1, n, 1, idx - 1);
    i64 right = query(1, 1, n, idx + 1, n);
    i64 ans = max(left, right);
    cout << ans << endl;
    updateRange(1, 1, n, idx, idx, arr[idx]);
  }
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#include <iostream>

using namespace std;
#define CIN ios_base::sync_with_stdio(0)
#define mx 200007
#define i64 long long

i64 arr[mx], tree[3 * mx], lazy[3 * mx];

void BuildTree(i64 node, i64 b, i64 e) {
  if (b == e) {
    tree[node] = arr[b];
    return;
  }

  i64 mid = (b + e) / 2;
  i64 left = 2 * node, right = 2 * node + 1;

  BuildTree(left, b, mid);
  BuildTree(right, mid + 1, e);

  tree[node] = max(tree[left], tree[right]);
}

i64 query(i64 node, i64 b, i64 e, i64 l, i64 r) {
  if (b > r || b > e || e < l) {
    return INT_MIN; // return 0 as sum;
  }

  if (lazy[node] != 0) {
    tree[node] += (e - b + 1) * lazy[node];

    if (b != e) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }

  if (b >= l && e <= r) {
    return tree[node];
  }

  i64 mid = (b + e) / 2, left = node * 2, right = node * 2 + 1;
  i64 lft = query(left, b, mid, l, r);
  i64 rgt = query(right, mid + 1, e, l, r);

  return max(lft, rgt);
}

void updateRange(i64 node, i64 b, i64 e, i64 l, i64 r, i64 value) {
  if (lazy[node] != 0) {
    tree[node] += (e - b + 1) * lazy[node];

    if (b != e) {
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    lazy[node] = 0;
  }

  if (b > e || b > r || e < l) {
    // start > end or start > r or end < l ....out of range
    return;
  }

  if (b >= l && e <= r) {
    // fully cover range [l....r]
    tree[node] += (e - b + 1) * value;

    if (b != e) {
      // not a leaf
      lazy[node * 2] += value;
      lazy[node * 2 + 1] += value;
    }
    return; // why ? dud
  }

  i64 mid = (b + e) / 2, left = node * 2, right = node * 2 + 1;

  updateRange(left, b, mid, l, r, value);
  updateRange(right, mid + 1, e, l, r, value);

  tree[node] = max(tree[left], tree[right]);
}

int main() {
  CIN;
  i64 t, qu, q, p, a;
  i64 val;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> arr[i];

  BuildTree(1, 1, n);
  memset(lazy, 0, sizeof lazy);

  for (int i = 1; i <= n; i++) {
    int idx = i;
    updateRange(1, 1, n, idx, idx, -arr[idx]);

    i64 left = query(1, 1, n, 1, idx - 1);
    i64 right = query(1, 1, n, idx + 1, n);
    i64 ans = max(left, right);
    cout << ans << endl;
    updateRange(1, 1, n, idx, idx, arr[idx]);
  }
  return 0;
}