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

#include <iostream>
using namespace std;

int dp[2][4][10 + 1 << 20];
int int_pow(int n, int p) {
  int x = 1;
  for (int i = 0; i < p; i++) {
    x *= n;
    x %= 100000;
  }
  return x;
}
int main() {
  int M, N;
  cin >> M >> N;
  int Q = 0;
  string s = "";
  for (int i = 0; i < M; i++) {
    string f;
    cin >> f;
    s += f;
    for (int j = 0; j < N; j++) {
      if (f[j] == '?')
        Q++;
    }
  }
  Q = int_pow(3, Q);
  switch (s[0]) {
  case 'J':
    dp[0][0][0] = 1;
    break;
  case 'O':
    dp[0][1][0] = 1;
    break;
  case 'I':
    dp[0][2][0] = 1;
    break;
  case '?':
    dp[0][0][0] = 1;
    dp[0][1][0] = 1;
    dp[0][2][0] = 1;
    break;
  }
  for (int i = 0; i < M * N - 1; i++) {
    switch (s[i + 1]) {
    case 'J':
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][0][t] += dp[i % 2][j][k];
          if (dp[(i + 1) % 2][0][t] >= 100000)
            dp[(i + 1) % 2][0][t] -= 100000;
        }
      }
      break;
    case 'O':

      if ((i + 1) % N != 0) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][1][1 + t] += dp[i % 2][0][k];
          if (dp[(i + 1) % 2][1][1 + t] >= 100000)
            dp[(i + 1) % 2][1][1 + t] -= 100000;
        }
        for (int j = 1; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            if (dp[(i + 1) % 2][1][t] >= 100000)
              dp[(i + 1) % 2][1][t] -= 100000;
          }
        }
      } else {
        for (int j = 0; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            if (dp[(i + 1) % 2][1][t] >= 100000)
              dp[(i + 1) % 2][1][t] -= 100000;
          }
        }
      }
      break;
    case 'I':
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][2][t] += dp[i % 2][j][k];
          if (t & (1 << (N - 1)))
            dp[(i + 1) % 2][2][t] = 0;
          if (dp[(i + 1) % 2][2][t] >= 100000)
            dp[(i + 1) % 2][2][t] -= 100000;
        }
      }
      break;
    case '?':
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][0][t] += dp[i % 2][j][k];
          if (dp[(i + 1) % 2][0][t] >= 100000)
            dp[(i + 1) % 2][0][t] -= 100000;
        }
      }

      if ((i + 1) % N != 0) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][1][1 + t] += dp[i % 2][0][k];
          if (dp[(i + 1) % 2][1][1 + t] >= 100000)
            dp[(i + 1) % 2][1][1 + t] -= 100000;
        }
        for (int j = 1; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            if (dp[(i + 1) % 2][1][t] >= 100000)
              dp[(i + 1) % 2][1][t] -= 100000;
          }
        }
      } else {
        for (int j = 0; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            if (dp[(i + 1) % 2][1][t] >= 100000)
              dp[(i + 1) % 2][1][t] -= 100000;
          }
        }
      }
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][2][t] += dp[i % 2][j][k];
          if (t & (1 << (N - 1)))
            dp[(i + 1) % 2][2][t] = 0;
          if (dp[(i + 1) % 2][2][t] >= 100000)
            dp[(i + 1) % 2][2][t] -= 100000;
        }
      }
      break;
    }

    for (int j = 0; j < 3; j++) {
      for (int k = 0; k < (1 << N); k++) {
        // cout<<i+1<<" "<<j<<" "<<k<<" "<<dp[(i+1)%2][j][k]<<endl;
        dp[i % 2][j][k] = 0;
      }
    }
  }
  int ans = 0;
  for (int j = 0; j < 3; j++) {
    for (int k = 0; k < (1 << N); k++) {
      ans += dp[(M * N - 1) % 2][j][k];
      ans %= 100000;
    }
  }
  ans = Q - ans;
  if (ans < 0)
    ans += 100000;
  cout << ans << endl;
}

Error: TLE

Fixed submission:

#include <iostream>
using namespace std;

int dp[2][4][10 + 1 << 20];
int int_pow(int n, int p) {
  int x = 1;
  for (int i = 0; i < p; i++) {
    x *= n;
    x %= 100000;
  }
  return x;
}
int main() {
  int M, N;
  cin >> M >> N;
  int Q = 0;
  string s = "";
  for (int i = 0; i < M; i++) {
    string f;
    cin >> f;
    s += f;
    for (int j = 0; j < N; j++) {
      if (f[j] == '?')
        Q++;
    }
  }
  Q = int_pow(3, Q);
  switch (s[0]) {
  case 'J':
    dp[0][0][0] = 1;
    break;
  case 'O':
    dp[0][1][0] = 1;
    break;
  case 'I':
    dp[0][2][0] = 1;
    break;
  case '?':
    dp[0][0][0] = 1;
    dp[0][1][0] = 1;
    dp[0][2][0] = 1;
    break;
  }
  for (int i = 0; i < M * N - 1; i++) {
    switch (s[i + 1]) {
    case 'J':
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][0][t] += dp[i % 2][j][k];
          dp[(i + 1) % 2][0][t] %= 100000;
        }
      }
      break;
    case 'O':
      if ((i + 1) % N != 0) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][1][1 + t] += dp[i % 2][0][k];
          dp[(i + 1) % 2][1][1 + t] %= 100000;
        }
        for (int j = 1; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            dp[(i + 1) % 2][1][t] %= 100000;
          }
        }
      } else {
        for (int j = 0; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            dp[(i + 1) % 2][1][t] %= 100000;
          }
        }
      }
      break;
    case 'I':
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][2][t] += dp[i % 2][j][k];
          if (t & (1 << (N - 1)))
            dp[(i + 1) % 2][2][t] = 0;
          dp[(i + 1) % 2][2][t] %= 100000;
        }
      }
      break;
    case '?':
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][0][t] += dp[i % 2][j][k];
          dp[(i + 1) % 2][0][t] %= 100000;
        }
      }
      if ((i + 1) % N != 0) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][1][1 + t] += dp[i % 2][0][k];
          dp[(i + 1) % 2][1][1 + t] %= 100000;
        }
        for (int j = 1; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            dp[(i + 1) % 2][1][t] %= 100000;
          }
        }
      } else {
        for (int j = 0; j < 3; j++) {
          for (int k = 0; k < (1 << N); k++) {
            int t = k << 1;
            t &= ~(1 << N);
            dp[(i + 1) % 2][1][t] += dp[i % 2][j][k];
            dp[(i + 1) % 2][1][t] %= 100000;
          }
        }
      }
      for (int j = 0; j < 3; j++) {
        for (int k = 0; k < (1 << N); k++) {
          int t = k << 1;
          t &= ~(1 << N);
          dp[(i + 1) % 2][2][t] += dp[i % 2][j][k];
          if (t & (1 << (N - 1)))
            dp[(i + 1) % 2][2][t] = 0;
          dp[(i + 1) % 2][2][t] %= 100000;
        }
      }
      break;
    }

    for (int j = 0; j < 3; j++) {
      for (int k = 0; k < (1 << N); k++) {
        // cout<<i+1<<" "<<j<<" "<<k<<" "<<dp[(i+1)%2][j][k]<<endl;
        dp[i % 2][j][k] = 0;
      }
    }
  }
  int ans = 0;
  for (int j = 0; j < 3; j++) {
    for (int k = 0; k < (1 << N); k++) {
      ans += dp[(M * N - 1) % 2][j][k];
      ans %= 100000;
    }
  }
  ans = Q - ans;
  if (ans < 0)
    ans += 100000;
  cout << ans << endl;
}