Problem p00482 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i, a) for (auto &i : a)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define RFOR(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; i--)
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define ALL(a) (a).begin(), (a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  EACH(x, vec) is >> x;
  return is;
}
/*
template<class... T>
ostream& operator<<(ostream& os, tuple<T...>& t) {
        for (size_t i = 0; i < tuple_size< tuple<T...> >::value; ++i) {
                if (i) os << " ";
                os << get<0>(t);
        }
        return os;
}
*/
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, vector<vector<T>> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

int H, W;
int dp[2][1 << 19][2][2] = {0};
vector<string> m(H);
bool inRange(int x, int y) { return 0 <= x && x < W && 0 <= y && y < H; }
char getM(int x, int y) {
  if (!inRange(x, y))
    return 0;
  switch (m[y][x]) {
  case 'J':
    return 0;
  case 'O':
    return 1;
  case 'I':
    return 2;
  }
  return -1;
}
bool check(int x, int y, int c) {
  if (getM(x, y) < 0)
    return true;
  return c == getM(x, y);
}
ll mod = 1e5;
int add(ll a, ll b) { return (a + b) % mod; }
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  cin >> H >> W;
  if (W == 1 || H == 1) {
    cout << 0 << endl;
    return 0;
  }
  m.resize(H);
  cin >> m;
  reverse(ALL(m));
  REP(i, m.size()) reverse(ALL(m[i]));
  fill(dp[0][0][0], dp[1][(1 << 19) - 1][2], 0);
  dp[0][0][0][0] = 1;
  REP(i, W * H) {
    fill(dp[i + 1 & 1][0][0], dp[i + 1 & 1][(1 << 19) - 1][2], 0);
    int x = i % W, y = i / W;
    REP(j, (1 << (W - 1))) REP(m, 3) {
      if (!check(x, y, m))
        continue;
      if (x == 0) {
        REP(k, 2) REP(l, 2) {
          int nj = j;
          int nk = m == 1 ? 1 : 0;
          dp[i + 1 & 1][nj][nk][l] =
              add(dp[i + 1 & 1][nj][nk][l], dp[i & 1][j][k][l]);
        }
      } else {
        REP(k, 2) REP(l, 2) {
          int nj = j >> 1;
          if (m == 2)
            nj |= (1 << (W - 2));
          int nk = m == 1 ? 1 : 0;
          int nl = l == 1 || (m == 0 && (j & 1) && k == 1) ? 1 : 0;
          dp[i + 1 & 1][nj][nk][nl] =
              add(dp[i + 1 & 1][nj][nk][nl], dp[i & 1][j][k][l]);
        }
      }
    }
  }
  ll ans = 0;
  REP(i, (1 << (W - 1))) REP(j, 2) { ans = add(ans, dp[(W * H) & 1][i][j][1]); }
  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;

#define EACH(i, a) for (auto &i : a)
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define RFOR(i, a, b) for (ll i = (b)-1; i >= (a); i--)
#define REP(i, n) for (ll i = 0; i < (n); i++)
#define RREP(i, n) for (ll i = (n)-1; i >= 0; i--)
#define debug(x) cout << #x << ": " << x << endl
#define pb push_back
#define ALL(a) (a).begin(), (a).end()

const ll linf = 1e18;
const int inf = 1e9;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  EACH(x, vec) is >> x;
  return is;
}
/*
template<class... T>
ostream& operator<<(ostream& os, tuple<T...>& t) {
        for (size_t i = 0; i < tuple_size< tuple<T...> >::value; ++i) {
                if (i) os << " ";
                os << get<0>(t);
        }
        return os;
}
*/
template <typename T> ostream &operator<<(ostream &os, vector<T> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T> ostream &operator<<(ostream &os, vector<vector<T>> &vec) {
  REP(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}

int H, W;
int dp[2][1 << 19][2][2] = {0};
vector<string> m(H);
bool inRange(int x, int y) { return 0 <= x && x < W && 0 <= y && y < H; }
char getM(int x, int y) {
  if (!inRange(x, y))
    return 0;
  switch (m[y][x]) {
  case 'J':
    return 0;
  case 'O':
    return 1;
  case 'I':
    return 2;
  }
  return -1;
}
bool check(int x, int y, int c) {
  if (getM(x, y) < 0)
    return true;
  return c == getM(x, y);
}
ll mod = 1e5;
int add(ll a, ll b) { return a + b > mod ? a + b - mod : a + b; }
int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  cin >> H >> W;
  if (W == 1 || H == 1) {
    cout << 0 << endl;
    return 0;
  }
  m.resize(H);
  cin >> m;
  reverse(ALL(m));
  REP(i, m.size()) reverse(ALL(m[i]));
  fill(dp[0][0][0], dp[1][(1 << 19) - 1][2], 0);
  dp[0][0][0][0] = 1;
  REP(i, W * H) {
    fill(dp[i + 1 & 1][0][0], dp[i + 1 & 1][(1 << 19) - 1][2], 0);
    int x = i % W, y = i / W;
    REP(j, (1 << (W - 1))) REP(m, 3) {
      if (!check(x, y, m))
        continue;
      if (x == 0) {
        REP(k, 2) REP(l, 2) {
          int nj = j;
          int nk = m == 1 ? 1 : 0;
          dp[i + 1 & 1][nj][nk][l] =
              add(dp[i + 1 & 1][nj][nk][l], dp[i & 1][j][k][l]);
        }
      } else {
        REP(k, 2) REP(l, 2) {
          int nj = j >> 1;
          if (m == 2)
            nj |= (1 << (W - 2));
          int nk = m == 1 ? 1 : 0;
          int nl = l == 1 || (m == 0 && (j & 1) && k == 1) ? 1 : 0;
          dp[i + 1 & 1][nj][nk][nl] =
              add(dp[i + 1 & 1][nj][nk][nl], dp[i & 1][j][k][l]);
        }
      }
    }
  }
  ll ans = 0;
  REP(i, (1 << (W - 1))) REP(j, 2) { ans = add(ans, dp[(W * H) & 1][i][j][1]); }
  cout << ans << endl;
}