Problem p03056 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
#define mid ((l + r) >> 1)

const int N = 190;
char str[N][N];
int n, m, tmp, sum[N][N], dp[N][N][N][18];

bool check(int lx, int rx, int ly, int ry) {
  int res =
      sum[rx][ry] - sum[lx - 1][ry] - sum[rx][ly - 1] + sum[lx - 1][ly - 1];
  if (res == 0 || res == (rx - lx + 1) * (ry - ly + 1))
    return true;
  return false;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%s", str[i] + 1);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] +
                  (bool)(str[i][j] == '.');
  for (int x = 1; x <= n; ++x)
    for (int L = 1; L <= m + 1; ++L)
      for (int k = 0; k < 18; ++k)
        dp[x][L][L - 1][k] = 1 << 30;
  for (int x = 1; x <= n; ++x)
    for (int L = 1; L <= m; ++L)
      for (int R = L; R <= m; ++R) {
        int l = x, r = n, ans = l - 1;
        while (l <= r)
          check(x, mid, L, R) ? ans = mid, l = mid + 1 : r = mid - 1;
        dp[x][L][R][0] = ans;
      }
  for (tmp = 1; dp[1][1][m][tmp - 1] < n; ++tmp) {
    for (int x = 1; x <= n; ++x)
      for (int L = 1; L <= m; ++L)
        for (int R = L; R <= m; ++R)
          dp[x][L][R][tmp] = dp[dp[x][L][R][tmp - 1] + 1][L][R][tmp - 1];
    for (int x = 1; x <= n; ++x)
      for (int L = 1; L <= m; ++L)
        for (int R = L; R <= m; ++R) {
          int res = L;
          while (
              res < R &&
              min(dp[x][L][res][tmp - 1], dp[x][res + 1][R][tmp - 1]) <=
                  min(dp[x][L][res + 1][tmp - 1], dp[x][res + 2][R][tmp - 1]))
            ++res;
          dp[x][L][R][tmp] =
              max(dp[x][L][R][tmp],
                  min(dp[x][L][res][tmp - 1], dp[x][res + 1][R][tmp - 1]));
        }
  }
  printf("%d\n", tmp - 1);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
using namespace std;
typedef long long ll;
#define mid ((l + r) >> 1)

const int N = 190;
char str[N][N];
int n, m, tmp, sum[N][N], dp[N][N][N][18];

bool check(int lx, int rx, int ly, int ry) {
  int res =
      sum[rx][ry] - sum[lx - 1][ry] - sum[rx][ly - 1] + sum[lx - 1][ly - 1];
  if (res == 0 || res == (rx - lx + 1) * (ry - ly + 1))
    return true;
  return false;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i)
    scanf("%s", str[i] + 1);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] +
                  (bool)(str[i][j] == '.');
  for (int x = 1; x <= n; ++x)
    for (int L = 1; L <= m + 1; ++L)
      for (int k = 0; k < 18; ++k)
        dp[x][L][L - 1][k] = 1 << 30;
  for (int x = 1; x <= n; ++x)
    for (int L = 1; L <= m; ++L)
      for (int R = L; R <= m; ++R) {
        int l = x, r = n, ans = l - 1;
        while (l <= r)
          check(x, mid, L, R) ? ans = mid, l = mid + 1 : r = mid - 1;
        dp[x][L][R][0] = ans;
      }
  for (tmp = 1; dp[1][1][m][tmp - 1] < n; ++tmp) {
    for (int x = 1; x <= n; ++x)
      for (int L = 1; L <= m; ++L)
        for (int R = L; R <= m; ++R)
          dp[x][L][R][tmp] = dp[dp[x][L][R][tmp - 1] + 1][L][R][tmp - 1];
    for (int x = 1; x <= n; ++x)
      for (int L = 1; L <= m; ++L)
        for (int R = L, res = L; R <= m; ++R) {
          while (
              res < R &&
              min(dp[x][L][res][tmp - 1], dp[x][res + 1][R][tmp - 1]) <=
                  min(dp[x][L][res + 1][tmp - 1], dp[x][res + 2][R][tmp - 1]))
            ++res;
          dp[x][L][R][tmp] =
              max(dp[x][L][R][tmp],
                  min(dp[x][L][res][tmp - 1], dp[x][res + 1][R][tmp - 1]));
        }
  }
  printf("%d\n", tmp - 1);
  return 0;
}