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

#include <bits/stdc++.h>
#define MAX_N 1005
using namespace std;
/*????¬??????????????????°???????????\\ O(H*W)*/
/*T????????????U????????´????????´????????¢???*/
typedef unsigned long long ull;
const ull A = 9999973, B = 950527; // A:???????´???°, B:?¨?????´???°

int H, W;
char T[MAX_N][MAX_N];
ull t[MAX_N][MAX_N];
ull t2[MAX_N][MAX_N];

int h, w;
char U[1005][1005];

void rol_hash2() {

  ull target = 0; //????????¨?????????????????\\
  for(int i=0; i<h ;i++){
  ull key = 0;
  for (int j = 0; j < w; j++)
    key = key * B + U[i][j];
  target = target * A + key;
}

ull C = 1;
for (int i = 0; i < w; i++)
  C *= B;

//?¨?????????????????????\\????????????
for (int i = 0; i < H; i++) {
  ull key = 0;
  for (int j = 0; j < W; j++) {
    key = key * B + T[i][j];
    if (j - w >= 0)
      key -= T[i][j - w] * C;
    t[i][j] = key;
    t2[i][j] = t[i][j];
  }
}

C = 1;
for (int i = 0; i < h; i++)
  C *= A;

//???????????????????????\\????????????
for (int i = 0; i < H; i++)
  for (int j = 0; j < W; j++) {
    if (i)
      t[i][j] += t[i - 1][j] * A;
    if (i - h >= 0)
      t[i][j] -= t2[i - h][j] * C;
    if (t[i][j] == target)
      if (i - h + 1 >= 0 && j - w + 1 >= 0)
        printf("%d %d\\n", i - h + 1, j - w + 1); //???????????§?¨??????????
  }
}

int main() {
  scanf("%d %d", &H, &W);
  for (int i = 0; i < H; i++)
    scanf("%s", T[i]);
  scanf("%d %d", &h, &w);
  for (int i = 0; i < h; i++)
    scanf("%s", U[i]);
  rol_hash2();
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define base 950527
#define base2 1777771
using namespace std;
typedef unsigned long long ull;
ull a[1001][1001], b[1001][1001], A[1001][1001], tmp[1001][1001], ans;

void Reverse(int p) {
  for (int i = 0; i < p; i++)
    reverse(b[i], b[i] + p);
}

void rol_90(int p) {
  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++)
      tmp[p - j - 1][i] = b[i][j];

  for (int i = 0; i < p; i++)
    for (int j = 0; j < p; j++)
      b[i][j] = tmp[i][j];
}

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

void in(int w, int h, ull tmp[1001][1001]) {
  string str[1001];
  for (int i = 0; i < h; i++)
    cin >> str[i];

  for (int i = 0; i < h; i++)
    for (int j = 0; j < (int)str[i].size(); j++) {
      int num = ctoi(str[i][j]);
      for (int k = 0; k < 6; k++)
        tmp[i][6 * j + 5 - k] = num & 1, num /= 2;
    }
}

set<ull> S;
void roll_hs(int w, int h, int p) {
  ull target = 0;
  for (int i = 0; i < p; i++) {
    ull k = 0;
    for (int j = 0; j < p; j++)
      k = k * base + b[i][j];
    target = target * base2 + k;
  }

  if (S.count(target))
    return;
  S.insert(target);

  memset(A, 0, sizeof(0));
  for (int i = 0; i < h; i++) {
    ull k = 0, l = 1;
    for (int j = 0; j < w; j++) {
      k = k * base + a[i][j];
      if (j - p >= 0)
        k -= l * a[i][j - p];
      else
        l *= base;
      A[i][j] = k;
    }
  }

  for (int j = p - 1; j < w; j++) {
    ull k = 0, l = 1;
    for (int i = 0; i < h; i++) {
      k = k * base2 + A[i][j];
      if (i - p >= 0)
        k -= l * A[i - p][j];
      else
        l *= base2;
      if (target == k && i >= p - 1)
        ans++;
    }
  }
}

int main() {
  while (1) {
    int w, h, p;
    cin >> w >> h >> p;
    if (!w && !h && !p)
      break;
    in(w, h, a), in(p, p, b);

    ans = 0, S.clear();
    for (int i = 0; i < 4; i++) {
      rol_90(p), roll_hs(w, h, p);
      Reverse(p), roll_hs(w, h, p), Reverse(p);
    }
    cout << ans << endl;
  }
  return 0;
}