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

#include <algorithm>
#include <map>
#include <stack>
#include <stdio.h>
#include <string.h>
using namespace std;

int h, w;
char m[512][512];

int AboveHeight(int x, int y) {
  int res = 0;
  while (m[y][x] == '.') {
    ++res;
    --y;
  }
  return res;
}

int Solve(int y) {
  typedef pair<int, int> P;
  int res = 0, x;
  stack<P> s;
  for (x = 1; x <= w + 1; ++x) {
    int a = AboveHeight(x, y);
    if (s.empty() || s.top().first <= a)
      s.push(P(a, x));
    else {
      int lastX = -1;
      while (!s.empty() && s.top().first > a) {
        P p = s.top();
        s.pop();
        res = max(res, p.first * (x - p.second));
        lastX = p.second;
      }
      s.push(P(a, lastX));
    }
  }
  return res;
}

int main() {
  while (scanf("%d%d", &h, &w), h) {
    memset(m, '*', sizeof(m));
    int x, y;
    int res = 0;
    for (y = 1; y <= h; ++y)
      scanf("%s", &m[y][1]);
    for (y = 1; y <= h; ++y)
      res = max(res, Solve(y));
    printf("%d\\n", res);
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <utility>
#include <vector>
using namespace std;
struct P {
  int x, y;
  P(int x, int y) : x(x), y(y) {}
  P() {}
  bool operator<(const P &p) const { return x - p.x ? x < p.x : y < p.y; }
  bool operator==(const P &p) const { return x == p.x && y == p.y; }
};
typedef vector<P> VP;

static int mark[512][512];
char map[512][512];
const char MARK = '*';
const int INF = 0x3F3F3F3F;

int minX[512], minY[512];

void ToEfficient(VP &refVec, P curP) {
  refVec.erase(
      remove_if(refVec.begin(), refVec.end(),
                [curP](P p) -> bool {
                  return (mark[curP.y][curP.x] - mark[curP.y][p.x - 1] -
                          mark[p.y - 1][curP.x] + mark[p.y - 1][p.x - 1]) != 0;
                }),
      refVec.end());

  memset(minX, INF, sizeof(minX));
  memset(minY, INF, sizeof(minY));
  for (int i = 0; i < refVec.size(); ++i) {
    const P &p = refVec[i];
    minX[p.y] = min(minX[p.y], p.x);
    minY[p.x] = min(minY[p.x], p.y);
  }
  refVec.erase(remove_if(refVec.begin(), refVec.end(),
                         [](P p) -> bool {
                           return (minX[p.y] < p.x) && (minY[p.x] < p.y);
                         }),
               refVec.end());
  sort(refVec.begin(), refVec.end());
  refVec.erase(unique(refVec.begin(), refVec.end()), refVec.end());
}

int main() {
  int h, w;
  while (scanf("%d%d", &h, &w), h) {
    memset(mark, 0, sizeof(mark));
    memset(map, 0, sizeof(map));
    int x, y;
    for (y = 1; y <= h; ++y)
      scanf("%s", &map[y][1]);

    for (y = 1; y <= h; ++y)
      for (x = 1; x <= w; ++x)
        mark[y][x] = mark[y - 1][x] + mark[y][x - 1] - mark[y - 1][x - 1] +
                     (map[y][x] == MARK);

    static VP dp[512][512];
    for (y = 0; y < 512; ++y)
      for (x = 0; x < 512; ++x)
        dp[y][x].clear();
    int res = 0;
    for (y = 1; y <= h; ++y) {
      for (x = 1; x <= w; ++x) {
        if (map[y][x] == MARK)
          continue;
        VP &refVec = dp[y][x];
        const VP &xVec = dp[y][x - 1], &yVec = dp[y - 1][x];
        refVec.reserve(xVec.size() + yVec.size() + 1);
        refVec.assign(yVec.begin(), yVec.end());
        refVec.insert(refVec.end(), xVec.begin(), xVec.end());
        refVec.push_back(P(x, y));

        ToEfficient(refVec, P(x, y));

        for (int i = 0; i < refVec.size(); ++i) {
          int area = (x - refVec[i].x + 1) * (y - refVec[i].y + 1);
          if (res < area)
            res = area;
        }
      }
    }
    printf("%d\\n", res);
  }
  return 0;
}