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

// Zory-2020
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll << (x))
#define fo(i, l, r) for (int i = (l), I = (r); i <= I; i++)
#define fd(i, r, l) for (int i = (r), I = (l); i >= I; i--)
#define mem(x, val) memset(x, val, sizeof x)
#define Swap(a, b, n)                                                          \\
  for (int I = 0; I <= n; I++)                                                 \\
  swap(a[I], b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug                                                                  \\
  if (DD)                                                                      \\
  printf("line %d\\n", __LINE__)
#define deb(x)                                                                 \\
  if (DD)                                                                      \\
  cerr << #x << '=' << x << endl
#define debug                                                                  \\
  if (DD)                                                                      \\
  printf
namespace mine {
ll qread() {
  ll ans = 0, f = 1;
  char c = getchar();
  while (c < '0' or c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while ('0' <= c and c <= '9')
    ans = ans * 10 + c - '0', c = getchar();
  return ans * f;
}
void write(ll num) {
  if (num < 0)
    putchar('-'), num = -num;
  if (num >= 10)
    write(num / 10);
  putchar('0' + num % 10);
}
void write1(ll num) {
  write(num);
  putchar(' ');
}
void write2(ll num) {
  write(num);
  putchar('\\n');
}
template <typename T> inline bool chmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T> inline bool chmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
bool IN(ll x, ll l, ll r) { return l <= x and x <= r; }
void gg() {
  write2(-1);
  exit(0);
}

const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
int mm(const int x) { return x >= MOD ? x - MOD : x; }
template <typename T> void add(T &x, const int &y) {
  x = (x + y >= MOD ? x + y - MOD : x + y);
}
ll qpower(ll x, ll e, int mod = MOD) {
  ll ans = 1;
  while (e) {
    if (e & 1)
      ans = ans * x % mod;
    x = x * x % mod;
    e >>= 1;
  }
  return ans;
}
ll invm(ll x) { return qpower(x, MOD - 2); }
const int N = 1e2 + 10;

ll C[N][N];
ll f[N][N][3], g[N][N][3]; // f=从行开始增加
char mp[N][N];
void main() {
  C[0][0] = 1;
  fo(i, 1, N - 1) {
    C[i][0] = 1;
    fo(j, 1, i) C[i][j] = mm(C[i - 1][j - 1] + C[i - 1][j]);
  }
  int n = qread(), m = qread();
  fo(i, 0, n - 1) scanf("%s", mp[i]);
  fo(mm, 0, m) g[n][mm][2] = C[m][mm] * bin(m - mm) % MOD;
  fd(nn, n, 0) fd(mm, m, 0) {
    fo(ad, 1, n - nn)
        add(f[nn][mm][0], C[ad + nn][nn] *
                              (g[nn + ad][mm][0] + g[nn + ad][mm][1] * 2 +
                               g[nn + ad][mm][2] * 2) %
                              MOD),
        add(f[nn][mm][1], C[ad + nn][nn] *
                              (g[nn + ad][mm][1] + g[nn + ad][mm][2]) % MOD *
                              (bin(ad) - 2) % MOD);
    fo(ad, 1, m - mm)
        add(g[nn][mm][0], C[ad + mm][mm] *
                              (f[nn][mm + ad][0] + f[nn][mm + ad][1] * 2 +
                               f[nn][mm + ad][2] * 2) %
                              MOD),
        add(g[nn][mm][1], C[ad + mm][mm] *
                              (f[nn][mm + ad][1] + f[nn][mm + ad][2]) % MOD *
                              (bin(ad) - 2) % MOD);
  }
  ll ans = g[n][0][2];
  fo(mm, 1, m) add(ans, f[0][mm][1]);
  fo(nn, 1, n) add(ans, g[nn][0][1]);
  deb(ans);
  fo(S1, 1, bin(n) - 1) fo(S2, 1, bin(m) - 1) {
    bool ok = 1;
    fo(i, 0, n - 1) if (S1 & bin(i)) {
      bool same = 1;
      int lst = -1;
      fo(j, 0, m - 1) if (S2 & bin(j)) same &=
          (lst < 0 or mp[i][j] == mp[i][lst]),
          lst = j;
      ok &= (same == 0);
    }
    fo(j, 0, m - 1) if (S2 & bin(j)) {
      bool same = 1;
      int lst = -1;
      fo(i, 0, n - 1) if (S1 & bin(i)) same &=
          (lst < 0 or mp[i][j] == mp[lst][j]),
          lst = i;
      ok &= (same == 0);
    }
    if (!ok)
      continue;
    fo(pp, 0, 2) add(ans, mm(f[PC(S1)][PC(S2)][pp] + g[PC(S1)][PC(S2)][pp]) *
                              invm(C[n][PC(S1)] * C[m][PC(S2)] % MOD) % MOD);
  }
  write(ans);
}
}; // namespace mine
signed main() {
  srand(time(0));
  mine::main();
}

Error: TLE

Fixed submission:

// Zory-2020
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll << (x))
#define fo(i, l, r) for (int i = (l), I = (r); i <= I; i++)
#define fd(i, r, l) for (int i = (r), I = (l); i >= I; i--)
#define mem(x, val) memset(x, val, sizeof x)
#define Swap(a, b, n)                                                          \\
  for (int I = 0; I <= n; I++)                                                 \\
  swap(a[I], b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug                                                                  \\
  if (DD)                                                                      \\
  printf("line %d\\n", __LINE__)
#define deb(x)                                                                 \\
  if (DD)                                                                      \\
  cerr << #x << '=' << x << endl
#define debug                                                                  \\
  if (DD)                                                                      \\
  printf
namespace mine {
ll qread() {
  ll ans = 0, f = 1;
  char c = getchar();
  while (c < '0' or c > '9') {
    if (c == '-')
      f = -1;
    c = getchar();
  }
  while ('0' <= c and c <= '9')
    ans = ans * 10 + c - '0', c = getchar();
  return ans * f;
}
void write(ll num) {
  if (num < 0)
    putchar('-'), num = -num;
  if (num >= 10)
    write(num / 10);
  putchar('0' + num % 10);
}
void write1(ll num) {
  write(num);
  putchar(' ');
}
void write2(ll num) {
  write(num);
  putchar('\\n');
}
template <typename T> inline bool chmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
template <typename T> inline bool chmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
bool IN(ll x, ll l, ll r) { return l <= x and x <= r; }
void gg() {
  write2(-1);
  exit(0);
}

const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int MOD = 998244353;
int mm(const int x) { return x >= MOD ? x - MOD : x; }
template <typename T> void add(T &x, const int &y) {
  x = (x + y >= MOD ? x + y - MOD : x + y);
}
ll qpower(ll x, ll e, int mod = MOD) {
  ll ans = 1;
  while (e) {
    if (e & 1)
      ans = ans * x % mod;
    x = x * x % mod;
    e >>= 1;
  }
  return ans;
}
ll invm(ll x) { return qpower(x, MOD - 2); }
const int N = 1e2 + 10;

ll C[N][N];
ll f[N][N][3], g[N][N][3]; // f=从行开始增加
char mp[N][N];
void main() {
  C[0][0] = 1;
  fo(i, 1, N - 1) {
    C[i][0] = 1;
    fo(j, 1, i) C[i][j] = mm(C[i - 1][j - 1] + C[i - 1][j]);
  }
  int n = qread(), m = qread();
  fo(i, 0, n - 1) scanf("%s", mp[i]);
  fo(mm, 0, m) g[n][mm][2] = C[m][mm] * bin(m - mm) % MOD;
  fd(nn, n, 0) fd(mm, m, 0) {
    fo(ad, 1, n - nn)
        add(f[nn][mm][0], C[ad + nn][nn] *
                              (g[nn + ad][mm][0] + g[nn + ad][mm][1] * 2 +
                               g[nn + ad][mm][2] * 2) %
                              MOD),
        add(f[nn][mm][1], C[ad + nn][nn] *
                              (g[nn + ad][mm][1] + g[nn + ad][mm][2]) % MOD *
                              (bin(ad) - 2) % MOD);
    fo(ad, 1, m - mm)
        add(g[nn][mm][0], C[ad + mm][mm] *
                              (f[nn][mm + ad][0] + f[nn][mm + ad][1] * 2 +
                               f[nn][mm + ad][2] * 2) %
                              MOD),
        add(g[nn][mm][1], C[ad + mm][mm] *
                              (f[nn][mm + ad][1] + f[nn][mm + ad][2]) % MOD *
                              (bin(ad) - 2) % MOD);
    debug("f(%d,%d)={%d,%d,%d}\\n", nn, mm, f[nn][mm][0], f[nn][mm][1],
          f[nn][mm][2]);
    debug("g(%d,%d)={%d,%d,%d}\\n", nn, mm, g[nn][mm][0], g[nn][mm][1],
          g[nn][mm][2]);
  }
  ll ans = g[n][0][2];
  fo(mm, 1, m) add(ans, f[0][mm][1]);
  fo(nn, 1, n) add(ans, g[nn][0][1]);
  deb(ans);
  fo(S1, 1, bin(n) - 1) fo(S2, 1, bin(m) - 1) {
    bool ok = 1;
    fo(i, 0, n - 1) if (S1 & bin(i)) {
      bool same = 1;
      int lst = -1;
      fo(j, 0, m - 1) if (S2 & bin(j)) same &=
          (lst < 0 or mp[i][j] == mp[i][lst]),
          lst = j;
      ok &= (same == 0);
    }
    fo(j, 0, m - 1) if (S2 & bin(j)) {
      bool same = 1;
      int lst = -1;
      fo(i, 0, n - 1) if (S1 & bin(i)) same &=
          (lst < 0 or mp[i][j] == mp[lst][j]),
          lst = i;
      ok &= (same == 0);
    }
    if (!ok)
      continue;
    fo(pp, 0, 2) add(ans, mm(f[PC(S1)][PC(S2)][pp] + g[PC(S1)][PC(S2)][pp]) *
                              invm(C[n][PC(S1)] * C[m][PC(S2)] % MOD) % MOD);
    debug("S1=%d S2=%d ans=%d\\n", S1, S2, ans);
  }
  write(ans);
}
}; // namespace mine
signed main() {
  // freopen("a.in","r",stdin);
  freopen("z.txt", "r", stdin);
  srand(time(0));
  mine::main();
}