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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop                                                                   \\
  char nyaa;                                                                   \\
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
const ld eps = 1e-6;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;

int h, w, p;
int trans(char t) {
  if ('A' <= t && t <= 'Z')
    return t - 'A';
  else if ('a' <= t && t <= 'z')
    return t - 'a' + 26;
  else if ('0' <= t && t <= '9')
    return t - '0' + 52;
  else if (t == '+')
    return 62;
  else
    return 63;
}
bool b[1000][1000];
bool c[100][100][8];

ll mod_pow(ll x, ll n, ll m) {
  ll ret = 1;
  while (n) {
    if (n % 2)
      ret = ret * x % m;
    x = x * x % m;
    n >>= 1;
  }
  return ret;
}
const ll m1 = mod + 2;
const ll m2 = 999999937;
ll invm;

ll hashb[1000][1000];
ll hashinv[1000][1000];
ll rsum[1000][1000];
void init2() {
  rep(i, h) {
    rep(j, w) {
      rsum[i][j] = 0;
      if (b[i][j]) {
        rsum[i][j] += hashb[i][j];
      }
      if (i > 0) {
        rsum[i][j] += rsum[i - 1][j];
      }
      if (j > 0) {
        rsum[i][j] += rsum[i][j - 1];
      }
      if (i > 0 && j > 0) {
        rsum[i][j] -= rsum[i - 1][j - 1];
      }
      rsum[i][j] = (rsum[i][j] % m1 + m1) % m1;
    }
  }
}

void init() {
  invm = mod_pow(m2, m1 - 2, m1);
  ll u = 1;
  ll invu = 1;
  rep(i, 1000) {
    rep(j, 1000) {
      hashb[i][j] = u;
      hashinv[i][j] = invu;
      u = u * m2 % m1;
      invu = invu * invm % m1;
    }
  }
}

void solve() {
  rep(i, h) {
    rep(j, (w + 5) / 6) {
      char t;
      cin >> t;
      int u = trans(t);
      rep(k, 6) {
        int nex = 6 * j + k;
        if (nex >= w)
          break;
        if (u & (1 << (5 - k)))
          b[i][nex] = true;
        else
          b[i][nex] = false;
      }
    }
  }
  rep(i, p) {
    rep(j, (p + 5) / 6) {
      char t;
      cin >> t;
      int u = trans(t);
      rep(k, 6) {
        int nex = 6 * j + k;
        if (nex >= p)
          break;
        if (u & (1 << (5 - k))) {
          c[i][nex][0] = true;
          c[i][p - 1 - nex][4] = true;
        } else {
          c[i][nex][0] = false;
          c[i][p - 1 - nex][4] = false;
        }
      }
    }
  }
  rep1(id, 3) {
    rep(i, p) {
      rep(j, p) {
        c[i][j][id] = c[p - 1 - j][i][id - 1];
        c[i][j][id + 4] = c[p - 1 - j][i][id + 3];
      }
    }
  }
  init2();

  ll z[8] = {};
  rep(id, 8) {
    rep(i, p) {
      rep(j, p) {
        if (c[i][j][id]) {
          z[id] += hashb[i][j];
        }
      }
    }
    z[id] %= m1;
  }

  int ans = 0;
  rep(i, h - p + 1) {
    rep(j, w - p + 1) {
      ll sum = rsum[i + p - 1][j + p - 1];
      if (i > 0) {
        sum -= rsum[i - 1][j + p - 1];
      }
      if (j > 0) {
        sum -= rsum[i + p - 1][j - 1];
      }
      if (i > 0 && j > 0) {
        sum += rsum[i - 1][j - 1];
      }
      sum = (sum % m1 + m1) % m1;
      sum = sum * hashinv[i][j] % m1;
      bool f = false;
      rep(id, 8) {
        if (z[id] == sum) {
          f = true;
          break;
        }
      }
      if (f)
        ans++;
    }
  }
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  init();
  while (cin >> w >> h >> p, h)
    solve();
  // solve();
  // stop
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 1000000007;
typedef double ld;
typedef complex<ld> Point;
const ll INF = mod * mod;
typedef pair<int, int> P;
#define stop                                                                   \\
  char nyaa;                                                                   \\
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
const ld eps = 1e-6;
const ld pi = acos(-1.0);
typedef pair<ld, ld> LDP;
typedef pair<ll, ll> LP;
typedef vector<int> vec;

int h, w, p;
int trans(char t) {
  if ('A' <= t && t <= 'Z')
    return t - 'A';
  else if ('a' <= t && t <= 'z')
    return t - 'a' + 26;
  else if ('0' <= t && t <= '9')
    return t - '0' + 52;
  else if (t == '+')
    return 62;
  else
    return 63;
}
bool b[1000][1000];
bool c[100][100][4];
bool rc[100][100][4];

void solve() {
  rep(i, h) {
    rep(j, (w + 5) / 6) {
      char t;
      cin >> t;
      int u = trans(t);
      rep(k, 6) {
        int nex = 6 * j + k;
        if (nex >= w)
          break;
        if (u & (1 << (5 - k)))
          b[i][nex] = true;
        else
          b[i][nex] = false;
      }
    }
  }
  rep(i, p) {
    rep(j, (p + 5) / 6) {
      char t;
      cin >> t;
      int u = trans(t);
      rep(k, 6) {
        int nex = 6 * j + k;
        if (nex >= p)
          break;
        if (u & (1 << (5 - k))) {
          c[i][nex][0] = true;
          rc[i][p - 1 - nex][0] = true;
        } else {
          c[i][nex][0] = false;
          rc[i][p - 1 - nex][0] = false;
        }
      }
    }
  }
  rep1(id, 3) {
    rep(i, p) {
      rep(j, p) {
        c[i][j][id] = c[p - 1 - j][i][id - 1];
        rc[i][j][id] = rc[p - 1 - j][i][id - 1];
      }
    }
  }
  int ans = 0;
  rep(i, h - p + 1) {
    rep(j, w - p + 1) {
      bool f = false;
      rep(id, 4) {
        bool g = true;
        rep(x, p) rep(y, p) {
          if (b[i + x][j + y] != c[x][y][id]) {
            g = false;
            break;
          }
        }
        if (g) {
          f = true;
          break;
        }
      }
      rep(id, 4) {
        bool g = true;
        rep(x, p) rep(y, p) {
          if (b[i + x][j + y] != rc[x][y][id]) {
            g = false;
            break;
          }
        }
        if (g) {
          f = true;
          break;
        }
      }
      if (f)
        ans++;
    }
  }
  cout << ans << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  while (cin >> w >> h >> p, h)
    solve();
  // solve();
  // stop
  return 0;
}