Problem p00482 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define FI first
#define SE second
#define PB push_back
#define MT make_tuple
using namespace std;
typedef tuple<int, int> TI1;
typedef tuple<int, int, int> TI2;
static const int INF = 1ll << 24;
static const int MBIT = 1048576;
static const int mod = 100000;
static const int dx[] = {
    1,
    -1,
    0,
    0,
};
static const int dy[] = {0, 0, 1, -1};

short N, M;
short fld[21 * 21];
int dp[2][3][MBIT];
int ans = 0;
int all = 1;
int main() {
  // int sum = 0;
  // for (int i = 0; i < 20; ++i)sum += pow(2, i);
  // cout << sum << " " << (int)pow(2, 20) << endl;
  cin >> N >> M;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      char c;
      cin >> c;
      if (c == '?')
        fld[i * M + j] = 3, all *= 3;
      if (c == 'J')
        fld[i * M + j] = 0;
      if (c == 'O')
        fld[i * M + j] = 1;
      if (c == 'I')
        fld[i * M + j] = 2;
      all %= mod;
    }
  }
  if (fld[0] != 3)
    dp[0][fld[0]][0] = 1;
  else {
    dp[0][0][0] = 1;
    dp[0][1][0] = 1;
    dp[0][2][0] = 1;
  }
  int maxbit = 0;
  for (int i = 0; i < M; ++i) {
    maxbit += pow(2, i);
  }
  int bit = 1 << M;
  int bit1 = 1 << (M - 1);
  int bit2 = 1 << (M - 2);
  for (int i = 0; i < M * N - 1; ++i) {
    int p1 = (i + 1) & 1;
    int p2 = i & 1;
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k <= maxbit; ++k) {
        int t1 = k << 1;
        if (t1 & bit)
          t1 -= bit;
        int t2 = t1 + 1;
        if ((k & bit1) && j == 2 && (i + 1) % M != 0)
          continue;
        if (fld[i + 1] == 3) {
          dp[p1][0][t1] = (dp[p1][0][t1] + dp[p2][j][k]) % mod;
          if (!(k & bit2) || (i + 2) % M == 0)
            dp[p1][2][t1] = (dp[p1][2][t1] + dp[p2][j][k]) % mod;
          if (j == 0 && (i + 1) % M != 0)
            dp[p1][1][t2] = (dp[p1][1][t2] + dp[p2][j][k]) % mod;
          else
            dp[p1][1][t1] = (dp[p1][1][t1] + dp[p2][j][k]) % mod;
        } else if (fld[i + 1] == 0) {
          dp[p1][0][t1] = (dp[p1][0][t1] + dp[p2][j][k]) % mod;
        } else if (fld[i + 1] == 1) {
          if (j == 0 && (i + 1) % M != 0)
            dp[p1][1][t2] = (dp[p1][1][t2] + dp[p2][j][k]) % mod;
          else
            dp[p1][1][t1] = (dp[p1][1][t1] + dp[p2][j][k]) % mod;
        } else if (fld[i + 1] == 2) {
          if (!(k & bit2) || (i + 2) % M == 0)
            dp[p1][2][t1] = (dp[p1][2][t1] + dp[p2][j][k]) % mod;
        }
        dp[p2][j][k] = 0;
      }
    }
  }
  for (int j = 0; j < 3; ++j) {
    for (int k = 0; k <= maxbit; ++k) {
      ans += dp[(M * N - 1) & 1][j][k];
      ans %= mod;
    }
  }
  cout << (all % mod - ans % mod + mod) % mod << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#define FI first
#define SE second
#define PB push_back
#define MT make_tuple
using namespace std;
typedef tuple<int, int> TI1;
typedef tuple<int, int, int> TI2;
static const int INF = 1ll << 24;
static const int MBIT = 1 << 20;
static const int mod = 100000;
static const int dx[] = {
    1,
    -1,
    0,
    0,
};
static const int dy[] = {0, 0, 1, -1};

int N, M;
int fld[21 * 21];
int dp[2][3][MBIT];
int ans = 0;
int all = 1;
int main() {
  cin >> N >> M;
  for (int i = 0; i < N; ++i) {
    for (int j = 0; j < M; ++j) {
      char c;
      cin >> c;
      if (c == '?')
        fld[i * M + j] = 3, all *= 3;
      if (c == 'J')
        fld[i * M + j] = 0;
      if (c == 'O')
        fld[i * M + j] = 1;
      if (c == 'I')
        fld[i * M + j] = 2;
      all %= mod;
    }
  }
  if (fld[0] != 3)
    dp[0][fld[0]][0] = 1;
  else {
    dp[0][0][0] = 1;
    dp[0][1][0] = 1;
    dp[0][2][0] = 1;
  }
  int maxbit = 0;
  for (int i = 0; i < M; ++i) {
    maxbit += pow(2, i);
  }
  int bit = 1 << M;
  int bit1 = 1 << (M - 1);
  int bit2 = 1 << (M - 2);
  for (int i = 0; i < M * N - 1; ++i) {
    int p1 = (i + 1) & 1;
    int p2 = i & 1;
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k <= maxbit; ++k) {
        int t1 = k << 1;
        if (t1 & bit)
          t1 -= bit;
        int t2 = t1 + 1;
        if ((k & bit1) && j == 2 && (i + 1) % M != 0)
          continue;
        if (fld[i + 1] == 3) {
          dp[p1][0][t1] = (dp[p1][0][t1] + dp[p2][j][k]) % mod;
          if (!(k & bit2) || (i + 2) % M == 0)
            dp[p1][2][t1] = (dp[p1][2][t1] + dp[p2][j][k]) % mod;
          if (j == 0 && (i + 1) % M != 0)
            dp[p1][1][t2] = (dp[p1][1][t2] + dp[p2][j][k]) % mod;
          else
            dp[p1][1][t1] = (dp[p1][1][t1] + dp[p2][j][k]) % mod;
        } else if (fld[i + 1] == 0) {
          dp[p1][0][t1] = (dp[p1][0][t1] + dp[p2][j][k]) % mod;
        } else if (fld[i + 1] == 1) {
          if (j == 0 && (i + 1) % M != 0)
            dp[p1][1][t2] = (dp[p1][1][t2] + dp[p2][j][k]) % mod;
          else
            dp[p1][1][t1] = (dp[p1][1][t1] + dp[p2][j][k]) % mod;
        } else if (fld[i + 1] == 2) {
          if (!(k & bit2) || (i + 2) % M == 0)
            dp[p1][2][t1] = (dp[p1][2][t1] + dp[p2][j][k]) % mod;
        }
        dp[p2][j][k] = 0;
      }
    }
  }
  for (int j = 0; j < 3; ++j) {
    for (int k = 0; k <= maxbit; ++k) {
      ans += dp[(M * N - 1) & 1][j][k];
      ans %= mod;
    }
  }
  cout << (all % mod - ans % mod + mod) % mod << endl;
  return 0;
}