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

/*
    もう寝よう！
 */

#include <cctype>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;

#define B1 (810893ULL)
#define B2 (65521ULL)
#define MOD (4294967291ULL)

typedef unsigned long long int ULLI;

int w;
int h;
int p;
int len;
int ans;
char buf[200];
ULLI line[100];
ULLI lhash[1000][1000];
ULLI sqhash[1000][1000];
bool tmpvec[100][100];
bool pattern[100][100];
bool image[1000][1000];
bool used[1000][1000];

void append(bool *v, int &idx, int k) {
  for (int i = 5; i >= 0; i--) {
    int t = (k >> i) & 1;
    v[idx++] = t;
  }
}

void input(bool *vecs, int length, int w, int h) {
  for (int i = 0; i < h; i++) {
    int idx = 0;

    scanf("%s", buf);

    len = strlen(buf);
    for (int j = 0; j < len; j++) {
      if (isupper(buf[j])) {
        append(vecs + length * i, idx, buf[j] - 'A');
      } else if (islower(buf[j])) {
        append(vecs + length * i, idx, buf[j] - 'a' + 26);
      } else if (isdigit(buf[j])) {
        append(vecs + length * i, idx, buf[j] - '0' + 52);
      } else if (buf[j] == '+') {
        append(vecs + length * i, idx, 62);
      } else if (buf[j] == '/') {
        append(vecs + length * i, idx, 63);
      }
    }
  }
}

void rotate() {
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      tmpvec[p - 1 - j][i] = pattern[i][j];
    }
  }

  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      pattern[i][j] = tmpvec[i][j];
    }
  }
}

void mirror() {
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      tmpvec[p - 1 - i][j] = pattern[i][j];
    }
  }

  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      pattern[i][j] = tmpvec[i][j];
    }
  }
}
void count() {
  ULLI hash = 0ULL;
  int ret = 0;

  for (int i = 0; i < p; i++) {
    line[i] = 0ULL;

    for (int j = 0; j < p; j++) {
      line[i] = (line[i] * B1 + (ULLI)pattern[i][j]) % MOD;
    }
    hash = (hash * B2 + line[i]) % MOD;
  }

  for (int i = 0; i <= h - p; i++) {
    for (int j = 0; j <= w - p; j++) {
      if (sqhash[i][j] == hash && !used[i][j]) {
        ++ans;
        used[i][j] = true;
      }
    }
  }
}

int main() {
  while (1) {
    scanf("%d%d%d", &w, &h, &p);
    if (w == 0 && h == 0 && p == 0)
      return 0;

    input((bool *)image, 1000, w, h);
    input((bool *)pattern, 100, p, p);

    if (w < p || h < p) {
      puts("0");
      continue;
    }

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        lhash[i][j] = 0ULL;
        sqhash[i][j] = 0ULL;
      }
    }

    for (int i = 0; i < h; i++) {
      ULLI sub = 1ULL;

      for (int j = 0; j < p; j++) {
        lhash[i][0] = (lhash[i][0] * B1 + (ULLI)image[i][j]) % MOD;
        sub = (sub * B1) % MOD;
      }

      for (int j = p; j < w; j++) {
        lhash[i][j - p + 1] = (lhash[i][j - p] * B1 + (ULLI)image[i][j]) % MOD;
        lhash[i][j - p + 1] =
            (lhash[i][j - p + 1] + MOD - sub * (ULLI)image[i][j - p] % MOD) %
            MOD;
      }
    }

    for (int j = 0; j <= w - p; j++) {
      ULLI sub = 1ULL;

      for (int i = 0; i < p; i++) {
        sqhash[0][j] = (sqhash[0][j] * B2 + (ULLI)lhash[i][j]) % MOD;
        sub = (sub * B2) % MOD;
      }

      for (int i = p; i < h; i++) {
        sqhash[i - p + 1][j] =
            (sqhash[i - p][j] * B2 + (ULLI)lhash[i][j]) % MOD;
        sqhash[i - p + 1][j] =
            (sqhash[i - p + 1][j] + MOD - sub * (ULLI)lhash[i - p][j] % MOD) %
            MOD;
      }
    }

    ans = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        used[i][j] = false;
      }
    }

    for (int i = 0; i < 4; i++) {
      count();
      rotate();
    }
    mirror();
    for (int i = 0; i < 4; i++) {
      count();
      rotate();
    }

    printf("%d\\n", ans);
  }
}

Error: MLE

Fixed submission:

#include <cctype>
#include <cstdio>
#include <cstring>
#include <map>
#include <utility>
#include <vector>
using namespace std;

#define B1 (810893ULL)
#define B2 (65521ULL)
#define MOD (4294967291ULL)

typedef unsigned long long int ULLI;
typedef pair<int, int> Pair;

int w;
int h;
int p;
int len;
char buf[200];
ULLI line[100];
ULLI lhash[1000][1000];
ULLI sqhash[1000][1000];
bool tmpvec[100][100];
bool pattern[100][100];
bool image[1000][1000];
map<Pair, bool> ans;

void append(bool *v, int &idx, int k) {
  for (int i = 5; i >= 0; i--) {
    int t = (k >> i) & 1;
    v[idx++] = t;
  }
}

void input(bool *vecs, int length, int w, int h) {
  for (int i = 0; i < h; i++) {
    int idx = 0;

    scanf("%s", buf);

    len = strlen(buf);
    for (int j = 0; j < len; j++) {
      if (isupper(buf[j])) {
        append(vecs + length * i, idx, buf[j] - 'A');
      } else if (islower(buf[j])) {
        append(vecs + length * i, idx, buf[j] - 'a' + 26);
      } else if (isdigit(buf[j])) {
        append(vecs + length * i, idx, buf[j] - '0' + 52);
      } else if (buf[j] == '+') {
        append(vecs + length * i, idx, 62);
      } else if (buf[j] == '/') {
        append(vecs + length * i, idx, 63);
      }
    }
  }
}

void rotate() {
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      tmpvec[p - 1 - j][i] = pattern[i][j];
    }
  }

  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      pattern[i][j] = tmpvec[i][j];
    }
  }
}

void mirror() {
  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      tmpvec[p - 1 - i][j] = pattern[i][j];
    }
  }

  for (int i = 0; i < p; i++) {
    for (int j = 0; j < p; j++) {
      pattern[i][j] = tmpvec[i][j];
    }
  }
}
void count() {
  ULLI hash = 0ULL;
  int ret = 0;

  for (int i = 0; i < p; i++) {
    line[i] = 0ULL;

    for (int j = 0; j < p; j++) {
      line[i] = (line[i] * B1 + (ULLI)pattern[i][j]) % MOD;
    }
    hash = (hash * B2 + line[i]) % MOD;
  }

  for (int i = 0; i <= h - p; i++) {
    for (int j = 0; j <= w - p; j++) {
      if (sqhash[i][j] == hash)
        ans[Pair(i, j)] = true;
    }
  }
}

int main() {
  while (1) {
    scanf("%d%d%d", &w, &h, &p);
    if (w == 0 && h == 0 && p == 0)
      return 0;

    input((bool *)image, 1000, w, h);
    input((bool *)pattern, 100, p, p);

    if (w < p || h < p) {
      puts("0");
      continue;
    }

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        lhash[i][j] = 0ULL;
        sqhash[i][j] = 0ULL;
      }
    }

    for (int i = 0; i < h; i++) {
      ULLI sub = 1ULL;

      for (int j = 0; j < p; j++) {
        lhash[i][0] = (lhash[i][0] * B1 + (ULLI)image[i][j]) % MOD;
        sub = (sub * B1) % MOD;
      }

      for (int j = p; j < w; j++) {
        lhash[i][j - p + 1] = (lhash[i][j - p] * B1 + (ULLI)image[i][j]) % MOD;
        lhash[i][j - p + 1] =
            (lhash[i][j - p + 1] + MOD - sub * (ULLI)image[i][j - p] % MOD) %
            MOD;
      }
    }

    for (int j = 0; j <= w - p; j++) {
      ULLI sub = 1ULL;

      for (int i = 0; i < p; i++) {
        sqhash[0][j] = (sqhash[0][j] * B2 + (ULLI)lhash[i][j]) % MOD;
        sub = (sub * B2) % MOD;
      }

      for (int i = p; i < h; i++) {
        sqhash[i - p + 1][j] =
            (sqhash[i - p][j] * B2 + (ULLI)lhash[i][j]) % MOD;
        sqhash[i - p + 1][j] =
            (sqhash[i - p + 1][j] + MOD - sub * (ULLI)lhash[i - p][j] % MOD) %
            MOD;
      }
    }

    ans.clear();
    for (int i = 0; i < 4; i++) {
      count();
      rotate();
    }
    mirror();
    for (int i = 0; i < 4; i++) {
      count();
      rotate();
    }

    printf("%u\\n", (unsigned int)ans.size());
  }
}