Problem p03833 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#define ll long long
using namespace std;
const int maxn = 5010, inf = 1e9;
int n, m;
int a[maxn], b[maxn][maxn], st[maxn];
ll sum[maxn], Sum[maxn], mp[maxn][maxn];
void read(int &k) {
  int f = 1;
  k = 0;
  char c = getchar();
  while (c < '0' || c > '9')
    c == '-' && (f = -1), c = getchar();
  while (c <= '9' && c >= '0')
    k = k * 10 + c - '0', c = getchar();
  k *= f;
}
int main() {
  read(n);
  read(m);
  for (int i = 2; i <= n; i++)
    read(a[i]), sum[i] = sum[i - 1] + a[i];
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      read(b[i][j]);
  for (int i = 1; i <= m; i++) {
    int top = 0;
    b[n + 1][i] = inf;
    for (int j = 1; j <= n + 1; j++) {
      for (; top && b[j][i] >= b[st[top]][i]; top--) {
        int l = st[top - 1] + 1, r = j - 1, pos = st[top];
        //    			printf("qwq%d %d %d %d %d\n", i, l, pos, pos,
        //    r);
        mp[l][pos] += b[pos][i];
        mp[l][r + 1] -= b[pos][i];
        mp[pos + 1][pos] -= b[pos][i];
        mp[pos + 1][r + 1] += b[pos][i];
      }
      st[++top] = j;
    }
  }
  ll ans = 0;
  for (int i = 1; i <= n; i++) {
    ll now = 0;
    for (int j = i; j <= n; j++) {
      Sum[j] += mp[i][j];
      now += Sum[j];
      //    		printf("%d %d %lld %lld\n", i, j, now, sum[j]-sum[i-1]);
      if (i > j)
        continue;
      ans = max(ans, now - sum[j] + sum[i]);
    }
  }
  printf("%lld\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#define ll long long
using namespace std;
const int maxn = 5010, inf = 1e9;
int n, m;
int a[maxn], b[maxn][210], st[maxn];
ll sum[maxn], Sum[maxn], mp[maxn][maxn];
void read(int &k) {
  int f = 1;
  k = 0;
  char c = getchar();
  while (c < '0' || c > '9')
    c == '-' && (f = -1), c = getchar();
  while (c <= '9' && c >= '0')
    k = k * 10 + c - '0', c = getchar();
  k *= f;
}
int main() {
  read(n);
  read(m);
  for (int i = 2; i <= n; i++)
    read(a[i]), sum[i] = sum[i - 1] + a[i];
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
      read(b[i][j]);
  for (int i = 1; i <= m; i++) {
    int top = 0;
    b[n + 1][i] = inf;
    for (int j = 1; j <= n + 1; j++) {
      for (; top && b[j][i] >= b[st[top]][i]; top--) {
        int l = st[top - 1] + 1, r = j - 1, pos = st[top];
        //    			printf("qwq%d %d %d %d %d\n", i, l, pos, pos,
        //    r);
        mp[l][pos] += b[pos][i];
        mp[l][r + 1] -= b[pos][i];
        mp[pos + 1][pos] -= b[pos][i];
        mp[pos + 1][r + 1] += b[pos][i];
      }
      st[++top] = j;
    }
  }
  ll ans = 0;
  for (int i = 1; i <= n; i++) {
    ll now = 0;
    for (int j = i; j <= n; j++) {
      Sum[j] += mp[i][j];
      now += Sum[j];
      //    		printf("%d %d %lld %lld\n", i, j, now, sum[j]-sum[i-1]);
      if (i > j)
        continue;
      ans = max(ans, now - sum[j] + sum[i]);
    }
  }
  printf("%lld\n", ans);
  return 0;
}