Problem p03630 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

typedef long long LL;

namespace INPUT {
const int L = 1 << 15;
char _buf[L], *S, *T, c;
int n;
#define _gc                                                                    \
  (S == T                                                                      \
       ? (T = (S = _buf) + fread(_buf, 1, L, stdin), (S == T ? EOF : (*S++)))  \
       : (*S++))
void readi(int &X) {
  for (c = _gc; c < '0' || c > '9'; c = _gc)
    ;
  X = c & 15;
  for (c = _gc; c >= '0' && c <= '9'; X = X * 10 + (c & 15), c = _gc)
    ;
}
void reads(char *s) {
  for (c = _gc; c != '#' && c != '.'; c = _gc)
    ;
  s[n = 1] = c;
  for (c = _gc; c == '#' || c == '.'; s[++n] = c, c = _gc)
    ;
}
} // namespace INPUT
using INPUT ::readi;
using INPUT ::reads;

const int Maxn = 2005;

int N, M;
char a[Maxn][Maxn];
int st[Maxn], len[Maxn];
int Ans;

int main() {
  freopen("speech.in", "r", stdin), freopen("speech.out", "w", stdout);
  readi(N), readi(M);
  for (int i = 1; i <= N; i++) {
    reads(a[i]);
    for (int j = 1; j <= M; ++j)
      a[i][j] = (a[i][j] == '#' ? 1 : 0);
  }
  Ans = max(N, M);
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j < M; j++) {
      if (i > 1 && !(a[i - 1][j] ^ a[i][j] ^ a[i - 1][j + 1] ^ a[i][j + 1]))
        len[j]++;
      else
        len[j] = 1;
    }
    int tp = 0;
    for (int j = 1; j <= M; j++) {
      while (tp && len[st[tp - 1]] >= len[j]) {
        int x = st[--tp];
        if (!tp)
          Ans = max(Ans, j * len[x]);
        else
          Ans = max(Ans, (j - st[tp - 1]) * len[x]);
      }
      st[tp++] = j;
    }
  }
  printf("%d\n", Ans);
  return 0;
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace std;

typedef long long LL;

namespace INPUT {
const int L = 1 << 15;
char _buf[L], *S, *T, c;
int n;
#define _gc                                                                    \
  (S == T                                                                      \
       ? (T = (S = _buf) + fread(_buf, 1, L, stdin), (S == T ? EOF : (*S++)))  \
       : (*S++))
void readi(int &X) {
  for (c = _gc; c < '0' || c > '9'; c = _gc)
    ;
  X = c & 15;
  for (c = _gc; c >= '0' && c <= '9'; X = X * 10 + (c & 15), c = _gc)
    ;
}
void reads(char *s) {
  for (c = _gc; c != '#' && c != '.'; c = _gc)
    ;
  s[n = 1] = c;
  for (c = _gc; c == '#' || c == '.'; s[++n] = c, c = _gc)
    ;
}
} // namespace INPUT
using INPUT ::readi;
using INPUT ::reads;

const int Maxn = 2005;

int N, M;
char a[Maxn][Maxn];
int st[Maxn], len[Maxn];
int Ans;

int main() {
  readi(N), readi(M);
  for (int i = 1; i <= N; i++) {
    reads(a[i]);
    for (int j = 1; j <= M; ++j)
      a[i][j] = (a[i][j] == '#' ? 1 : 0);
  }
  Ans = max(N, M);
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j < M; j++) {
      if (i > 1 && !(a[i - 1][j] ^ a[i][j] ^ a[i - 1][j + 1] ^ a[i][j + 1]))
        len[j]++;
      else
        len[j] = 1;
    }
    int tp = 0;
    for (int j = 1; j <= M; j++) {
      while (tp && len[st[tp - 1]] >= len[j]) {
        int x = st[--tp];
        if (!tp)
          Ans = max(Ans, j * len[x]);
        else
          Ans = max(Ans, (j - st[tp - 1]) * len[x]);
      }
      st[tp++] = j;
    }
  }
  printf("%d\n", Ans);
  return 0;
}