Problem p03056 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mit map<int, int>::iterator
#define sit set<int>::iterator
#define itrm(g, x) for (mit g = x.begin(); g != x.end(); g++)
#define itrs(g, x) for (sit g = x.begin(); g != x.end(); g++)
#define ltype int
#define rep(i, j, k) for (ltype(i) = (j); (i) <= (k); (i)++)
#define rap(i, j, k) for (ltype(i) = (j); (i) < (k); (i)++)
#define per(i, j, k) for (ltype(i) = (j); (i) >= (k); (i)--)
#define pii pair<int, int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
#define fastio ios::sync_with_stdio(false)
const int inf = 0x3f3f3f3f, mod = 1000000007;
const double pi = 3.1415926535897932, eps = 1e-6;
int h, w;
char g[190][190];
int dp[190][190][190][18], lim, pre[190][190];
int query(int l, int r, int d, int u) {
  return pre[u][r] - pre[d - 1][r] - pre[u][l - 1] + pre[d - 1][l - 1];
}
int dfs(int i, int l, int r, int k) {
  int &res = dp[i][l][r][k];
  if (res != -1)
    return res;
  int aa = query(l, r, i, h);
  if (aa == 0 || aa == (r - l + 1) * (h - i + 1))
    return res = 0;
  res = max(res, dfs(dfs(i, l, r, k - 1) + 1, l, r, k - 1));
  int dl = l, dr = r - 1;
  while (dl < dr) {
    int mid = (dl + dr) >> 1;
    if (dfs(i, l, mid, k) < dfs(i, mid + 1, r, k))
      l = mid + 1;
    else
      r = mid;
  }
  res = max(res, min(dp[i][l][dl][k], dp[i][dl + 1][r][k]));
  if (dl != l)
    res = max(res, min(dp[i][l][dl - 1][k], dp[i][dl][r][k]));
  return res;
}
int logg(int x) {
  int res = 0;
  while (x)
    res++, x >>= 1;
  return res;
}
int main() {
  freopen("data.in", "r", stdin);
  freopen("ans1.out", "w", stdout);
  scanf("%d%d", &h, &w);
  rep(i, 1, h) scanf("%s", g[i] + 1);
  lim = logg(h - 1) + logg(w - 1);
  rep(i, 1, h) rep(j, 1, w) rep(k, 1, h) rep(m, 0, lim) dp[i][j][k][m] = -1;
  rep(i, 1, h) rep(j, 1, w) pre[i][j] =
      pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + (g[i][j] == '#');
  per(i, h, 1) rep(k, 0, lim) rep(len, 1, w) rep(l, 1, w) {
    int r = l + len - 1;
    if (r > w)
      break;
    int &res = dp[i][l][r][k];
    // if(res!=-1) continue;
    res = i - 1;
    int dl = i, dr = h;
    while (dl < dr) {
      int mid = (dl + dr + 1) >> 1;
      int x = query(l, r, i, mid);
      if ((x == 0) || (x == (r - l + 1) * (mid - i + 1)))
        dl = mid;
      else
        dr = mid - 1;
    }
    int x = query(l, r, i, i);
    if (!(x == 0 || x == r - l + 1))
      dl = i - 1;
    res = dl;
    if (k) {
      // printf("%d %d %d %d is going\n",i,l,r,k);
      int nxt = dp[i][l][r][k - 1] + 1;
      if (nxt > h)
        res = h;
      else
        res = max(res, dp[nxt][l][r][k - 1]);
      // rap(w,l,r) printf("%d %d\n",dp[i][l][w][k-1],dp[i][w+1][r][k-1]);
      int dl = l, dr = r - 1;
      while (dl < dr) {
        int mid = (dl + dr) >> 1;
        if (dp[i][l][mid][k - 1] > dp[i][mid + 1][r][k - 1])
          dl = mid + 1;
        else
          dr = mid;
      }
      // printf("%d\n",dl);
      if (dl > l)
        res = max(res, min(dp[i][l][dl - 1][k - 1], dp[i][dl][r][k - 1]));
      if (dl < r)
        res = max(res, min(dp[i][l][dl + 1][k - 1], dp[i][dl + 2][r][k - 1]));
      res = max(res, min(dp[i][l][dl][k - 1], dp[i][dl + 1][r][k - 1]));
      // printf("! %d %d",dp[i][l][dl][k-1],dp[i][dl+1][r][k-1]);
      // if(dl>l) printf(" %d %d",dp[i][l][dl-1][k-1],dp[i][dl][r][k-1]);
      // putchar('\n');
    }
  }
  rep(i, 0, lim) if (dp[1][1][w][i] == h) {
    printf("%d\n", i);
    return 0;
  }
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define mit map<int, int>::iterator
#define sit set<int>::iterator
#define itrm(g, x) for (mit g = x.begin(); g != x.end(); g++)
#define itrs(g, x) for (sit g = x.begin(); g != x.end(); g++)
#define ltype int
#define rep(i, j, k) for (ltype(i) = (j); (i) <= (k); (i)++)
#define rap(i, j, k) for (ltype(i) = (j); (i) < (k); (i)++)
#define per(i, j, k) for (ltype(i) = (j); (i) >= (k); (i)--)
#define pii pair<int, int>
#define fi first
#define se second
#define mpr make_pair
#define pb push_back
#define fastio ios::sync_with_stdio(false)
const int inf = 0x3f3f3f3f, mod = 1000000007;
const double pi = 3.1415926535897932, eps = 1e-6;
int h, w;
char g[190][190];
int dp[190][190][190][18], lim, pre[190][190];
int query(int l, int r, int d, int u) {
  return pre[u][r] - pre[d - 1][r] - pre[u][l - 1] + pre[d - 1][l - 1];
}
int dfs(int i, int l, int r, int k) {
  int &res = dp[i][l][r][k];
  if (res != -1)
    return res;
  int aa = query(l, r, i, h);
  if (aa == 0 || aa == (r - l + 1) * (h - i + 1))
    return res = 0;
  res = max(res, dfs(dfs(i, l, r, k - 1) + 1, l, r, k - 1));
  int dl = l, dr = r - 1;
  while (dl < dr) {
    int mid = (dl + dr) >> 1;
    if (dfs(i, l, mid, k) < dfs(i, mid + 1, r, k))
      l = mid + 1;
    else
      r = mid;
  }
  res = max(res, min(dp[i][l][dl][k], dp[i][dl + 1][r][k]));
  if (dl != l)
    res = max(res, min(dp[i][l][dl - 1][k], dp[i][dl][r][k]));
  return res;
}
int logg(int x) {
  int res = 0;
  while (x)
    res++, x >>= 1;
  return res;
}
int main() {
  // freopen("data.in","r",stdin);
  // freopen("ans1.out","w",stdout);
  scanf("%d%d", &h, &w);
  rep(i, 1, h) scanf("%s", g[i] + 1);
  lim = logg(h - 1) + logg(w - 1);
  rep(i, 1, h) rep(j, 1, w) rep(k, 1, h) rep(m, 0, lim) dp[i][j][k][m] = -1;
  rep(i, 1, h) rep(j, 1, w) pre[i][j] =
      pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + (g[i][j] == '#');
  per(i, h, 1) rep(k, 0, lim) rep(len, 1, w) rep(l, 1, w) {
    int r = l + len - 1;
    if (r > w)
      break;
    int &res = dp[i][l][r][k];
    // if(res!=-1) continue;
    res = i - 1;
    int dl = i, dr = h;
    while (dl < dr) {
      int mid = (dl + dr + 1) >> 1;
      int x = query(l, r, i, mid);
      if ((x == 0) || (x == (r - l + 1) * (mid - i + 1)))
        dl = mid;
      else
        dr = mid - 1;
    }
    int x = query(l, r, i, i);
    if (!(x == 0 || x == r - l + 1))
      dl = i - 1;
    res = dl;
    if (k) {
      // printf("%d %d %d %d is going\n",i,l,r,k);
      int nxt = dp[i][l][r][k - 1] + 1;
      if (nxt > h)
        res = h;
      else
        res = max(res, dp[nxt][l][r][k - 1]);
      // rap(w,l,r) printf("%d %d\n",dp[i][l][w][k-1],dp[i][w+1][r][k-1]);
      int dl = l, dr = r - 1;
      while (dl < dr) {
        int mid = (dl + dr) >> 1;
        if (dp[i][l][mid][k - 1] > dp[i][mid + 1][r][k - 1])
          dl = mid + 1;
        else
          dr = mid;
      }
      // printf("%d\n",dl);
      if (dl > l)
        res = max(res, min(dp[i][l][dl - 1][k - 1], dp[i][dl][r][k - 1]));
      if (dl < r)
        res = max(res, min(dp[i][l][dl + 1][k - 1], dp[i][dl + 2][r][k - 1]));
      res = max(res, min(dp[i][l][dl][k - 1], dp[i][dl + 1][r][k - 1]));
      // printf("! %d %d",dp[i][l][dl][k-1],dp[i][dl+1][r][k-1]);
      // if(dl>l) printf(" %d %d",dp[i][l][dl-1][k-1],dp[i][dl][r][k-1]);
      // putchar('\n');
    }
  }
  rep(i, 0, lim) if (dp[1][1][w][i] == h) {
    printf("%d\n", i);
    return 0;
  }
  return 0;
}