Problem p03056 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define reg register
using namespace std;
int n, m;
char s[185][185];
int f[185][185];
short dp[185][185][185][21];

int pd(reg int sx, reg int sy, reg int ex, reg int ey) {
  return f[ex][ey] + f[sx - 1][sy - 1] - f[sx - 1][ey] - f[ex][sy - 1];
}

int main() {
  scanf("%d %d", &n, &m);
  for (reg int i = 1; i <= n; i++)
    scanf("%s", s[i] + 1);
  for (reg int i = 1; i <= n; i++) {
    for (reg int j = 1; j <= m; j++)
      f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + (s[i][j] == '#');
  }
  for (reg int i = 1; i <= n; i++) {
    for (reg int j1 = 1; j1 <= m; j1++) {
      for (reg int j2 = j1; j2 <= m; j2++) {
        reg int l = i, r = n, p = i - 1;
        while (l <= r) {
          reg int mid = (l + r) / 2;
          reg int tot = pd(i, j1, mid, j2);
          if (tot == 0 || tot == (mid - i + 1) * (j2 - j1 + 1))
            p = max(p, mid), l = mid + 1;
          else
            r = mid - 1;
        }
        dp[i][j1][j2][0] = (short)p;
      }
    }
  }
  for (reg int k = 1;; k++) {
    if (dp[1][1][m][k - 1] == n) {
      printf("%d\n", k - 1);
      return 0;
    }
    for (reg int len = 1; len <= m; len++) {
      for (reg int i = 1; i <= n; i++) {
        for (reg int j1 = 1; j1 <= m - len + 1; j1++) {
          reg int j2 = j1 + len - 1;
          if (dp[i][j1][j2][k - 1] == n) {
            dp[i][j1][j2][k] = n;
            continue;
          }
          reg int pre = (int)dp[i][j1][j2][k - 1] + 1;
          dp[i][j1][j2][k] = dp[pre][j1][j2][k - 1];
          if (dp[i][j1][j2][k] == n)
            continue;
          reg int l = j1, r = j2 - 1, p = 0;
          while (l <= r) {
            reg int mid = (l + r) / 2;
            reg int x = (int)dp[i][j1][mid][k - 1],
                    y = (int)dp[i][mid + 1][j2][k - 1];
            p = max(p, min(x, y));
            if (x < y)
              r = mid - 1;
            else
              l = mid + 1;
          }
          dp[i][j1][j2][k] = max(dp[i][j1][j2][k], (short)p);
        }
      }
    }
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define reg register
using namespace std;
int n, m;
char s[190][190];
int f[190][190];
short dp[190][190][190][21];

int pd(reg int sx, reg int sy, reg int ex, reg int ey) {
  return f[ex][ey] + f[sx - 1][sy - 1] - f[sx - 1][ey] - f[ex][sy - 1];
}

int main() {
  scanf("%d %d", &n, &m);
  for (reg int i = 1; i <= n; i++)
    scanf("%s", s[i] + 1);
  for (reg int i = 1; i <= n; i++) {
    for (reg int j = 1; j <= m; j++)
      f[i][j] = f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1] + (s[i][j] == '#');
  }
  for (reg int i = 1; i <= n; i++) {
    for (reg int j1 = 1; j1 <= m; j1++) {
      for (reg int j2 = j1; j2 <= m; j2++) {
        reg int l = i, r = n, p = i - 1;
        while (l <= r) {
          reg int mid = (l + r) / 2;
          reg int tot = pd(i, j1, mid, j2);
          if (tot == 0 || tot == (mid - i + 1) * (j2 - j1 + 1))
            p = max(p, mid), l = mid + 1;
          else
            r = mid - 1;
        }
        dp[i][j1][j2][0] = (short)p;
      }
    }
  }
  for (reg int k = 1;; k++) {
    if (dp[1][1][m][k - 1] == n) {
      printf("%d\n", k - 1);
      return 0;
    }
    for (reg int len = 1; len <= m; len++) {
      for (reg int i = 1; i <= n; i++) {
        for (reg int j1 = 1; j1 <= m - len + 1; j1++) {
          reg int j2 = j1 + len - 1;
          if (dp[i][j1][j2][k - 1] == n) {
            dp[i][j1][j2][k] = n;
            continue;
          }
          reg int pre = (int)dp[i][j1][j2][k - 1] + 1;
          dp[i][j1][j2][k] = dp[pre][j1][j2][k - 1];
          if (dp[i][j1][j2][k] == n)
            continue;
          reg int l = j1, r = j2 - 1, p = 0;
          while (l <= r) {
            reg int mid = (l + r) / 2;
            reg int x = (int)dp[i][j1][mid][k - 1],
                    y = (int)dp[i][mid + 1][j2][k - 1];
            p = max(p, min(x, y));
            if (x < y)
              r = mid - 1;
            else
              l = mid + 1;
          }
          dp[i][j1][j2][k] = max(dp[i][j1][j2][k], (short)p);
        }
      }
    }
  }

  return 0;
}