Problem p00116 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory.h>
#include <memory>
#include <numeric>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#define USE_MATH_DEFINES
using namespace std;

typedef complex<double> xy_t;
typedef pair<xy_t, xy_t> line;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<int, PP> PPP;
const int INF = 1 << 29;
const double EPS = 1E-10;

namespace std {
bool operator<(const xy_t &a, const xy_t &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}
} // namespace std

double cross(const xy_t &a, const xy_t &b) { return imag(conj(a) * b); }

double dot(const xy_t &a, const xy_t &b) { return real(conj(a) * b); }

int ccw(xy_t a, xy_t b, xy_t c) {
  b -= a;
  c -= a;
  if (cross(b, c) > 0)
    return 1;
  if (cross(b, c) < 0)
    return -1;
  if (dot(b, c) < 0)
    return +2;
  if (norm(b) < norm(c))
    return -2;
  return 0;
}

bool intersectSS(const line &s, const line &t) {
  return ccw(s.first, s.second, t.first) * ccw(s.first, s.second, t.second) <=
             0 &&
         ccw(t.first, t.second, s.first) * ccw(t.first, t.second, s.second) <=
             0;
}

xy_t crosspoint(const line &l, const line &m) {
  double a = cross(l.second - l.first, m.second - m.first);
  double b = cross(l.second - l.first, l.second - m.first);
  if (abs(a) < EPS && abs(b) < EPS)
    return m.first;
  if (abs(a) < EPS)
    assert(false);
  return m.first + b / a * (m.second - m.first);
}

int main() {
  int h, w;
  char field[502][502];
  int upper[600];
  int next[600];
  while (cin >> h >> w && (h || w)) {
    fill(&field[0][0], &field[501][501] + 1, '*');
    for (int i = 1; i <= h; i++) {
      for (int j = 1; j <= w; j++) {
        cin >> field[i][j];
      }
    }
    int ans = 0;
    upper[0] = h + 2;
    fill(next, next + 600, 0);
    for (int i = 1; i <= h; i++) {
      for (int j = 1; j <= w; j++) {
        if (field[i][j] == '*')
          upper[j] = h + 2;
        else if (field[i - 1][j] == '*') {
          upper[j] = i - 1;
        }

        if (upper[j - 1] > upper[j]) {
          next[j] = j - 1;
        } else if (field[i][j] != '*') {
          int p = j - 1;
          while (upper[p] <= upper[j]) {
            p = next[p];
          }
          next[j] = p;
        } else {
          next[j] = 0;
        }
        int a = upper[j];
        int b = next[j];
        while (a < i) {
          ans = max(ans, (i - a) * (j - b));
          a = upper[b];
          b = next[b];
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

struct size {
  int x, y;
};
const int max_size = 500;
char field[500][500];
int yx[500];
vector<size> dp[500][500];

int main() {
  int h, w;
  while (cin >> w >> h) {
    if (w == 0 && h == 0)
      break;
    for (int i = 0; i < max(h, w); i++) {
      yx[i] = 0;
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> field[i][j];
      }
    }
    size s;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (field[i][j] == '.') {
          if (i == 0) {
            if (j != 0) {
              if (field[i][j - 1] == '.') {
                int x = 0;
                while (j - x >= 0 && field[i][j - x] == '.')
                  x++;
                s.x = x;
                s.y = 1;
                dp[i][j].push_back(s);
              } else {
                s.x = 1;
                s.y = 1;
                dp[i][j].push_back(s);
              }
            } else {
              s.x = 1;
              s.y = 1;
            }
          } else {
            if (j == 0) {
              if (field[i - 1][j] == '.') {
                int y = 0;
                while (i - y >= 0 && field[i - y][j] == '.')
                  y++;
                s.x = 1;
                s.y = y;
                dp[i][j].push_back(s);
              } else {
                s.x = 1;
                s.y = 1;
                dp[i][j].push_back(s);
              }
            } else {
              if (field[i - 1][j] == '*' && field[i][j - 1] == '*') {
                s.x = 1;
                s.y = 1;
                dp[i][j].push_back(s);
              } else if (field[i - 1][j] == '*' && field[i][j - 1] == '.') {
                int x = 0;
                while (j - x >= 0 && field[i][j - x] == '.')
                  x++;
                s.x = x;
                s.y = 1;
                dp[i][j].push_back(s);
              } else if (field[i - 1][j] == '.' && field[i][j - 1] == '*') {
                int y = 0;
                while (i - y >= 0 && field[i - y][j] == '.')
                  y++;
                s.x = 1;
                s.y = y;
                dp[i][j].push_back(s);
              } else {
                int y = 0, x = 0;
                while (i - y >= 0 && field[i - y][j] == '.')
                  y++;
                while (j - x >= 0 && field[i][j - x] == '.')
                  x++;
                int yx[500];
                for (int k = 0; k < h; k++) {
                  yx[k] = 0;
                }
                for (vector<size>::iterator iter = dp[i - 1][j].begin();
                     iter != dp[i - 1][j].end(); iter++) {
                  s.y = (*iter).y + 1;
                  s.x = min(x, (*iter).x);
                  if (yx[s.y] < s.x) {
                    yx[s.y] = s.x;
                    dp[i][j].push_back(s);
                  }
                }
                for (vector<size>::iterator iter = dp[i][j - 1].begin();
                     iter != dp[i][j - 1].end(); iter++) {
                  s.x = (*iter).x + 1;
                  s.y = min((*iter).y, y);
                  if (yx[s.y] < s.x) {
                    yx[s.y] = s.x;
                    dp[i][j].push_back(s);
                  }
                }
              }
            }
          }
        }
      }
    }
    int max_size = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (vector<size>::iterator iter = dp[i][j].begin();
             iter != dp[i][j].end(); iter++) {
          max_size = max(max_size, (*iter).y * (*iter).x);
        }
        dp[i][j].clear();
      }
    }
    cout << max_size << endl;
  }
  return 0;
}