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

#include <iostream>
#include <map>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() { return val; }
    bool operator!=(Iterator &itr) { return val < itr.val; }
    void operator++() { ++val; }
  };
  Iterator i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

template <class T> T at(vector<T> v, int i) {
  return v[(i % (int)v.size() + v.size()) % v.size()];
}

const long long MOD = 100000;

class Inverse {
private:
  vector<long long> inv;

public:
  Inverse(int n) {
    inv = vector<long long>(n, 1);
    for (int i : range(2, n))
      inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
  }

  long long operator()(long long a) const {
    if (a < (int)inv.size())
      return inv[a];
    long long b = MOD, x = 1, y = 0;
    while (b) {
      long long t = a / b;
      swap(a -= t * b, b);
      swap(x -= t * y, y);
    }
    return (MOD + x % MOD) % MOD;
  }
};

Inverse inv(1000000);

class Mint {
private:
  long long val;

public:
  Mint() : val(0) {}
  Mint(long long val) : val(val % MOD) {}

  Mint operator+=(const Mint &m) {
    val += m.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }

  Mint operator-=(const Mint &m) {
    val -= m.val;
    if (val < 0)
      val += MOD;
    return *this;
  }

  Mint operator*=(const Mint &m) {
    val *= m.val;
    val %= MOD;
    return *this;
  }

  Mint operator/=(const Mint &m) {
    val *= inv(m.val);
    val %= MOD;
    return *this;
  }

  Mint operator+(const Mint &m) const {
    Mint res = *this;
    res += m;
    return res;
  }

  Mint operator-(const Mint &m) const {
    Mint res = *this;
    res -= m;
    return res;
  }

  Mint operator*(const Mint &m) const {
    Mint res = *this;
    res *= m;
    return res;
  }

  Mint operator/(const Mint &m) const {
    Mint res = *this;
    res /= m;
    return res;
  }

  Mint operator++() { return val += 1; }

  operator long long() { return val; }
};

ostream &operator<<(ostream &os, Mint a) {
  os << (long long)a;
  return os;
}

istream &operator>>(istream &is, Mint &a) {
  long long n;
  is >> n;
  a = Mint(n);
  return is;
}

int main() {
  int m, n;
  cin >> m >> n;
  vector<string> s(m);
  for (auto &i : s)
    cin >> i;
  vector<map<pair<int, int>, Mint>> dp(2);
  dp[0] = {{make_pair(0, 0), 1}};
  int mask = (1 << n) - 1;
  for (int y : range(m))
    for (int x : range(n)) {
      for (const auto &t : dp[0]) {
        int bit = t.first.first;
        int pre = t.first.second;
        Mint num = t.second;
        int nbit = 2 * bit & mask;
        if (s[y][x] == 'J' || s[y][x] == '?') {
          dp[1][make_pair(nbit, 0)] += num;
        }
        if (s[y][x] == 'O' || s[y][x] == '?') {
          if (x > 0 && pre == 0)
            dp[1][make_pair(nbit | 1, 1)] += num;
          else
            dp[1][make_pair(nbit, 1)] += num;
        }
        if (s[y][x] == 'I' || s[y][x] == '?') {
          if ((bit & 1 << (n - 2)) == 0)
            dp[1][make_pair(nbit, 2)] += num;
        }
      }
      dp[0] = dp[1];
      dp[1].clear();
    }
  Mint res = 1;
  for (const auto &i : s)
    for (const auto &j : i)
      if (j == '?')
        res *= 3;
  for (const auto &t : dp[0])
    res -= t.second;
  cout << res << endl;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <map>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() { return val; }
    bool operator!=(Iterator &itr) { return val < itr.val; }
    void operator++() { ++val; }
  };
  Iterator i, n;

public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator &begin() { return i; }
  Iterator &end() { return n; }
};

template <class T> T at(vector<T> v, int i) {
  return v[(i % (int)v.size() + v.size()) % v.size()];
}

const long long MOD = 100000;

class Inverse {
private:
  vector<long long> inv;

public:
  Inverse(int n) {
    inv = vector<long long>(n, 1);
    for (int i : range(2, n))
      inv[i] = inv[MOD % i] * (MOD - MOD / i) % MOD;
  }

  long long operator()(long long a) const {
    if (a < (int)inv.size())
      return inv[a];
    long long b = MOD, x = 1, y = 0;
    while (b) {
      long long t = a / b;
      swap(a -= t * b, b);
      swap(x -= t * y, y);
    }
    return (MOD + x % MOD) % MOD;
  }
};

Inverse inv(1000000);

class Mint {
private:
  long long val;

public:
  Mint() {}
  Mint(long long val) : val(val % MOD) {}

  Mint operator+=(const Mint &m) {
    val += m.val;
    if (val >= MOD)
      val -= MOD;
    return *this;
  }

  Mint operator-=(const Mint &m) {
    val -= m.val;
    if (val < 0)
      val += MOD;
    return *this;
  }

  Mint operator*=(const Mint &m) {
    val *= m.val;
    val %= MOD;
    return *this;
  }

  Mint operator/=(const Mint &m) {
    val *= inv(m.val);
    val %= MOD;
    return *this;
  }

  Mint operator+(const Mint &m) const {
    Mint res = *this;
    res += m;
    return res;
  }

  Mint operator-(const Mint &m) const {
    Mint res = *this;
    res -= m;
    return res;
  }

  Mint operator*(const Mint &m) const {
    Mint res = *this;
    res *= m;
    return res;
  }

  Mint operator/(const Mint &m) const {
    Mint res = *this;
    res /= m;
    return res;
  }

  Mint operator++() { return val += 1; }

  operator long long() { return val; }
};

ostream &operator<<(ostream &os, Mint a) {
  os << (long long)a;
  return os;
}

istream &operator>>(istream &is, Mint &a) {
  long long n;
  is >> n;
  a = Mint(n);
  return is;
}

bool isValidBit(const string &s, int bit) {
  for (int i : range(s.size() - 1))
    if (s.substr(i, 2) == "JO" && (bit & 1 << i) == 0)
      return false;
  for (int i : range(s.size() - 1))
    if (s[i] != 'J' && s[i] != '?' && (bit & 1 << i))
      return false;
  for (int i : range(s.size() - 1))
    if (s[i + 1] != 'O' && s[i + 1] != '?' && (bit & 1 << i))
      return false;
  return true;
}

int main() {
  int m, n;
  cin >> m >> n;
  vector<string> s(m);
  for (auto &i : s)
    cin >> i;
  vector<vector<pair<int, Mint>>> dp(2);
  vector<int> bits;
  for (int i : range(1 << (n - 1)))
    if ((i & i << 1) == 0)
      bits.emplace_back(i);
  dp[0].emplace_back(0, 1);
  for (int i : range(m)) {
    for (auto bit : bits) {
      if (!isValidBit(s[i], bit))
        continue;
      Mint p = 0;
      for (auto &t : dp[0]) {
        bool ok = true;
        for (int k : range(n - 1))
          if (t.first & 1 << k && s[i][k] == 'I')
            ok = false;
        if (!ok)
          continue;
        Mint p1 = 0, p2 = 0, p3 = 0;
        if (bit & 1) {
          p1 = 1;
        } else if (s[i][0] == 'J') {
          p1 = 1;
        } else if (s[i][0] == 'O') {
          p2 = 1;
        } else if (s[i][0] == 'I') {
          p3 = 1;
        } else {
          p1 = p2 = p3 = 1;
          if (t.first & 1)
            p3 = 0;
          if (s[i][1] == 'O')
            p1 = 0;
        }
        for (int j : range(1, n)) {
          if (s[i][j] == 'J' || bit & 1 << j) {
            p1 += p2 + p3;
            p2 = p3 = 0;
          } else if (s[i][j] == 'O' || (j > 0 && bit & 1 << (j - 1))) {
            p2 += p1 + p3;
            p1 = p3 = 0;
          } else if (s[i][j] == 'I') {
            p3 += p1 + p2;
            p1 = p2 = 0;
          } else {
            Mint pp1 = p1 + p2 + p3, pp2 = p2 + p3, pp3 = p1 + p2 + p3;
            if (t.first & 1 << j)
              pp3 = 0;
            if (j < n - 1 && s[i][j + 1] == 'O')
              pp1 = 0;
            p1 = pp1, p2 = pp2, p3 = pp3;
          }
        }
        p += (p1 + p2 + p3) * t.second;
      }
      if (p > 0)
        dp[1].emplace_back(bit, p);
    }
    dp[0] = dp[1];
    dp[1].clear();
  }
  Mint sum = 1;
  for (auto &i : s)
    for (auto j : i)
      if (j == '?')
        sum *= 3;
  for (auto &i : dp[0])
    sum -= i.second;
  cout << sum << endl;
}