Problem p03833 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define N 6000
#define int long long
using namespace std;
typedef long long ll;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, m, A[N], B[5010][N], ss[5010][N], tpp[5010];
ll tree[N << 2], Add[N << 2];
inline void deal(int ls, int rs, int x, int y) {
  tree[x] += y;
  Add[x] += y;
}
inline void pushup(int rt) { tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]); }
inline void pushdown(int ls, int rs, int rt) {
  if (Add[rt]) {
    deal(ls, rs, rt << 1, Add[rt]);
    deal(ls, rs, rt << 1 | 1, Add[rt]);
    Add[rt] = 0;
  }
}
inline void updata(int L, int R, int x, int l, int r, int rt) {
  if (L > R)
    return;
  if (L <= l && r <= R) {
    deal(L, R, rt, x);
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(L, R, rt);
  if (mid >= L)
    updata(L, R, x, l, mid, rt << 1);
  if (mid < R)
    updata(L, R, x, mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
inline void built(int l, int r, int rt) {
  if (l == r) {
    tree[rt] = A[l];
    return;
  }
  int mid = (l + r) >> 1;
  built(l, mid, rt << 1);
  built(mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
inline ll query(int L, int R, int l, int r, int rt) {
  if (L > R)
    return 0;
  if (L <= l && r <= R)
    return tree[rt];
  int mid = (l + r) >> 1;
  pushdown(L, R, rt);
  if (mid < L)
    return query(L, R, mid + 1, r, rt << 1 | 1);
  if (mid >= R)
    return query(L, R, l, mid, rt << 1);
  return max(query(L, R, l, mid, rt << 1),
             query(L, R, mid + 1, r, rt << 1 | 1));
}
inline void work(int x, int y) {
  // cerr <<"SPE:"<< x << " " << y << endl;
  updata(x, x, B[y][x], 1, n, 1);
  int nw = ss[y][tpp[y]];
  // cerr << "cg:" << endl;
  while (B[y][x] > B[y][ss[y][tpp[y]]] && tpp[y]) {
    //	cout << nw << " ";
    updata(ss[y][tpp[y] - 1] + 1, nw, B[y][x] - B[y][ss[y][tpp[y]]], 1, n, 1);
    nw = ss[y][tpp[y] - 1];
    tpp[y]--;
  }
  // cout << endl;
  ss[y][++tpp[y]] = x;
}
signed main() {
  freopen("read.in", "r", stdin);
  n = read();
  m = read();
  A[1] = 0;
  for (int i = 2; i <= n; i++)
    A[i] = read() + A[i - 1];
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      B[j][i] = read();
  built(1, n, 1);
  ll ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++)
      work(i, j);
    ans = max(ans, query(1, i, 1, n, 1) - 1ll * A[i]);
  }
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define N 6000
#define int long long
using namespace std;
typedef long long ll;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, m, A[N], B[5010][N], ss[5010][N], tpp[5010];
ll tree[N << 2], Add[N << 2];
inline void deal(int ls, int rs, int x, int y) {
  tree[x] += y;
  Add[x] += y;
}
inline void pushup(int rt) { tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]); }
inline void pushdown(int ls, int rs, int rt) {
  if (Add[rt]) {
    deal(ls, rs, rt << 1, Add[rt]);
    deal(ls, rs, rt << 1 | 1, Add[rt]);
    Add[rt] = 0;
  }
}
inline void updata(int L, int R, int x, int l, int r, int rt) {
  if (L > R)
    return;
  if (L <= l && r <= R) {
    deal(L, R, rt, x);
    return;
  }
  int mid = (l + r) >> 1;
  pushdown(L, R, rt);
  if (mid >= L)
    updata(L, R, x, l, mid, rt << 1);
  if (mid < R)
    updata(L, R, x, mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
inline void built(int l, int r, int rt) {
  if (l == r) {
    tree[rt] = A[l];
    return;
  }
  int mid = (l + r) >> 1;
  built(l, mid, rt << 1);
  built(mid + 1, r, rt << 1 | 1);
  pushup(rt);
}
inline ll query(int L, int R, int l, int r, int rt) {
  if (L > R)
    return 0;
  if (L <= l && r <= R)
    return tree[rt];
  int mid = (l + r) >> 1;
  pushdown(L, R, rt);
  if (mid < L)
    return query(L, R, mid + 1, r, rt << 1 | 1);
  if (mid >= R)
    return query(L, R, l, mid, rt << 1);
  return max(query(L, R, l, mid, rt << 1),
             query(L, R, mid + 1, r, rt << 1 | 1));
}
inline void work(int x, int y) {
  // cerr <<"SPE:"<< x << " " << y << endl;
  updata(x, x, B[y][x], 1, n, 1);
  int nw = ss[y][tpp[y]];
  // cerr << "cg:" << endl;
  while (B[y][x] > B[y][ss[y][tpp[y]]] && tpp[y]) {
    //	cout << nw << " ";
    updata(ss[y][tpp[y] - 1] + 1, nw, B[y][x] - B[y][ss[y][tpp[y]]], 1, n, 1);
    nw = ss[y][tpp[y] - 1];
    tpp[y]--;
  }
  // cout << endl;
  ss[y][++tpp[y]] = x;
}
signed main() {
  // freopen("read.in","r",stdin);
  n = read();
  m = read();
  A[1] = 0;
  for (int i = 2; i <= n; i++)
    A[i] = read() + A[i - 1];
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      B[j][i] = read();
  built(1, n, 1);
  ll ans = 0;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++)
      work(i, j);
    ans = max(ans, query(1, i, 1, n, 1) - 1ll * A[i]);
  }
  cout << ans << endl;
  return 0;
}