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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

struct RollingHash {
  int n;
  static const unsigned P = 1000000007U;
  vector<unsigned long long> pow, phash;
  RollingHash() : n(0) {}

  template <typename T> RollingHash(const T &s, unsigned long long Q = 1) {
    n = s.size();
    pow.resize(n + 1);
    phash.resize(n + 1);
    pow[0] = Q;
    phash[0] = 0;
    for (int i = 0; i < n; i++) {
      pow[i + 1] = pow[i] * P;
      phash[i + 1] = s[i] + phash[i] * P;
    }
  }
  unsigned long long get(int i) const { return phash[i]; }
  unsigned long long get(int i, int j) const {
    return get(j) - get(i) * pow[j - i];
  }
};

int H, W, P;
struct Pat {
  string b[100];
};

string b[1000];
RollingHash h[1000];

Pat ps[8];
RollingHash hs[8][100];

Pat rotate(Pat p) {
  Pat r;
  for (int i = 0; i < P; i++) {
    r.b[i] = string(P, '0');
  }
  for (int i = 0; i < P; i++) {
    for (int j = 0; j < P; j++) {
      r.b[j][P - 1 - i] = p.b[i][j];
    }
  }
  return r;
}

Pat mirror(Pat p) {
  Pat r;
  for (int i = 0; i < P; i++) {
    r.b[i] = string(P, '0');
    for (int j = 0; j < P; j++) {
      r.b[i][P - 1 - j] = p.b[i][j];
    }
  }
  return r;
}

int conv(char c) {
  if ('A' <= c && c <= 'Z')
    return c - 'A';
  if ('a' <= c && c <= 'z')
    return 26 + c - 'a';
  if (isdigit(c))
    return 52 + c - '0';
  if (c == '+')
    return 62;
  return 63;
}

void view(Pat p) {
  for (int i = 0; i < P; i++) {
    cout << p.b[i] << endl;
    ;
  }
  cout << endl;
}

int check(int x, int y, int k) {
  for (int i = 0; i < P; i++) {
    if (h[y + i].get(x, x + P) != hs[k][i].get(0, P))
      return false;
  }
  return true;
}

void solve() {
  int cnt = 0;
  for (int i = 0; i < H - P + 1; i++) {
    for (int j = 0; j < W - P + 1; j++) {
      for (int k = 0; k < 8; k++) {
        if (check(j, i, k)) {
          cnt++;
          break;
        }
      }
    }
  }
  cout << cnt << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (cin >> W >> H >> P, W | H | P) {
    for (int i = 0; i < H; i++) {
      b[i] = "";
      string s;
      cin >> s;
      for (int j = 0; j < s.size(); j++) {
        int x = conv(s[j]);
        for (int k = 0; k < 6; k++) {
          b[i] += char('0' + ((x >> (5 - k)) & 1));
        }
      }
      h[i] = RollingHash(b[i]);
    }

    Pat p;
    for (int i = 0; i < P; i++) {
      string s;
      cin >> s;
      for (int j = 0; j < s.size(); j++) {
        int x = conv(s[j]);
        for (int k = 0; k < 6; k++) {
          p.b[i] += char('0' + ((x >> (5 - k)) & 1));
        }
      }
    }

    int cnt = 0;
    for (int i = 0; i < 4; i++) {
      Pat m = mirror(p);
      ps[cnt] = p;
      for (int j = 0; j < P; j++) {
        hs[cnt][j] = RollingHash(p.b[j]);
      }
      cnt++;
      ps[cnt] = m;
      for (int j = 0; j < P; j++) {
        hs[cnt][j] = RollingHash(m.b[j]);
      }
      cnt++;
      p = rotate(p);
    }

    /*for(int i = 0; i < H; i++) {
            cout << b[i] << endl;
            }

            for(int i = 0; i < 8; i++) {
            view(ps[i]);
            }*/

    solve();
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>
using namespace std;

int H, W, P;
struct Pat {
  int b[100][100];
};

int b[1000][1000];
vector<Pat> ps;

Pat rotate(Pat p) {
  Pat r;
  for (int i = 0; i < P; i++) {
    for (int j = 0; j < P; j++) {
      r.b[j][P - 1 - i] = p.b[i][j];
    }
  }
  return r;
}

Pat mirror(Pat p) {
  Pat r;
  for (int i = 0; i < P; i++) {
    for (int j = 0; j < P; j++) {
      r.b[i][P - 1 - j] = p.b[i][j];
    }
  }
  return r;
}

int conv(char c) {
  if ('A' <= c && c <= 'Z')
    return c - 'A';
  if ('a' <= c && c <= 'z')
    return 26 + c - 'a';
  if (isdigit(c))
    return 52 + c - '0';
  if (c == '+')
    return 62;
  return 63;
}

void view(Pat p) {
  for (int i = 0; i < P; i++) {
    for (int j = 0; j < P; j++) {
      cout << p.b[i][j];
    }
    cout << endl;
  }
  cout << endl;
}

int check(int x, int y, int k) {
  for (int i = 0; i < P; i++) {
    for (int j = 0; j < P; j++) {
      if (b[y + i][x + j] != ps[k].b[i][j])
        return false;
    }
  }
  return true;
}

void solve() {
  int cnt = 0;
  for (int i = 0; i < H - P + 1; i++) {
    for (int j = 0; j < W - P + 1; j++) {
      for (int k = 0; k < 8; k++) {
        if (check(j, i, k)) {
          cnt++;
          break;
        }
      }
    }
  }
  cout << cnt << endl;
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  while (cin >> W >> H >> P, W | H | P) {
    for (int i = 0; i < H; i++) {
      string s;
      cin >> s;
      for (int j = 0; j < s.size(); j++) {
        int x = conv(s[j]);
        for (int k = 0; k < 6; k++) {
          b[i][6 * j + k] = (x >> (5 - k)) & 1;
        }
      }
    }

    Pat p;
    for (int i = 0; i < P; i++) {
      string s;
      cin >> s;
      for (int j = 0; j < s.size(); j++) {
        int x = conv(s[j]);
        for (int k = 0; k < 6; k++) {
          p.b[i][6 * j + k] = (x >> (5 - k)) & 1;
        }
      }
    }

    ps.clear();
    for (int i = 0; i < 4; i++) {
      Pat m = mirror(p);
      ps.push_back(p);
      ps.push_back(m);
      p = rotate(p);
    }

    /*	for(int i = 0; i < H; i++) {
                    for(int j = 0; j < W; j++) {
                    cout << b[i][j];
                    }
                    cout << endl;
                    }

                    for(int i = 0; i < 8; i++) {
                    view(ps[i]);
                    }*/

    solve();
  }
}