Problem p00098 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int, int> P;
typedef std::pair<int, P> State;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1},
          dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

int N;
int A[101][101];

int main() {
  std::cin >> N;

  FOR(i, 1, N + 1) {
    FOR(j, 1, N + 1) { std::cin >> A[i][j]; }
  }

  FOR(i, 1, N + 1) {
    FOR(j, 1, N + 1) { A[i][j] += A[i][j - 1]; }
  }

  FOR(i, 1, N + 1) {
    FOR(j, 1, N + 1) { A[i][j] += A[i - 1][j]; }
  }

  // FOR(i, 1, N+1){
  //     FOR(j, 1, N+1){
  //         printf("%d, ", A[i][j]);
  //     }
  //     puts("");
  // }

  int res = -INF;
  FOR(lx, 1, N + 1) {
    FOR(rx, lx, N + 1) {
      FOR(ly, 1, N + 1) {
        FOR(ry, ly, N + 1) {
          res = std::max(res, A[ry][rx] - A[ly - 1][rx] - A[ry][lx - 1] +
                                  A[ly - 1][lx - 1]);
        }
      }
    }
  }

  std::cout << res << std::endl;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define REP(i, j) FOR(i, 0, j)
#define mp std::make_pair

typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<int, int> P;
typedef std::pair<int, P> State;

const int INF = 1001001001;

// S N E W(南北東西)
const int dx[8] = {0, 0, 1, -1, 1, 1, -1, -1},
          dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};

const int MAX_N = 100;

class SegmentTree {
public:
  SegmentTree() {}
  SegmentTree(int n) { init(n); }
  void init(int n) {
    size = 1;
    while (size < n) {
      size *= 2;
    }

    REP(i, size * 2 - 1) { data[i] = 0; }
  }
  void update(int k, int v) {
    k += size - 1;
    data[k] = v;

    while (k > 0) {
      k = (k - 1) / 2;
      data[k] = data[k * 2 + 1] + data[k * 2 + 2];
    }
  }
  int query(int l, int r) { return _query(l, r, 0, 0, size); }

private:
  int _query(int a, int b, int k, int l, int r) {
    if (b <= l || r <= a) {
      return 0;
    }
    if (a <= l && r <= b) {
      return data[k];
    }
    return _query(a, b, 2 * k + 1, l, (l + r) / 2) +
           _query(a, b, 2 * k + 2, (l + r) / 2, r);
  }
  int data[MAX_N * 4], size;
};

class SegmentTree_2D {
public:
  SegmentTree_2D() {}
  SegmentTree_2D(int n) { init(n); }
  void init(int n) {
    size = 1;
    while (size < n) {
      size *= 2;
    }
    REP(i, size * 2 - 1) { st[i].init(n); }
  }
  void update(int x, int y, int v) {
    y += size - 1;
    st[y].update(x, v);
    while (y > 0) {
      y = (y - 1) / 2;
      st[y].update(x, st[y * 2 + 1].query(x, x + 1) +
                          st[y * 2 + 2].query(x, x + 1));
    }
  }
  int query(int lx, int ly, int rx, int ry) {
    return _query(lx, ly, rx, ry, 0, 0, size);
  }

private:
  int _query(int lx, int ly, int rx, int ry, int k, int l, int r) {
    if (ry <= l || r <= ly) {
      return 0;
    }
    if (ly <= l && r <= ry) {
      return st[k].query(lx, rx);
    }
    return _query(lx, ly, rx, ry, k * 2 + 1, l, (l + r) / 2) +
           _query(lx, ly, rx, ry, k * 2 + 2, (l + r) / 2, r);
  }
  SegmentTree st[MAX_N * 4];
  int size;
};

int N;
SegmentTree_2D st;

int main() {
  std::cin >> N;
  st.init(N);

  REP(i, N) {
    REP(j, N) {
      int a;
      std::cin >> a;
      st.update(j, i, a);
    }
  }

  int res = -INF;
  REP(lx, N) {
    FOR(rx, lx + 1, N + 1) {
      REP(ly, N) {
        FOR(ry, ly + 1, N + 1) {
          res = std::max(res, st.query(lx, ly, rx, ry));
        }
      }
    }
  }

  std::cout << res << std::endl;
}