Problem p00891 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
long long H, W, K, c[1002][1002], p[1002][1002], r1[1002][1002], r2[1002][1002],
    r3[1002][1002];
long long power[1000002], mod = 1000000007;
vector<long long> v;
void makehush() {
  power[0] = 1;
  for (int i = 1; i < H * W; i++) {
    power[i] = power[i - 1] * 2;
    power[i] %= mod;
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      r1[i][j] = c[i][j] * power[i * W + j];
    }
  }
  for (int i = 1; i < H; i++) {
    for (int j = 0; j < W; j++) {
      r1[i][j] += r1[i - 1][j];
      r1[i][j] %= mod;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 1; j < W; j++) {
      r1[i][j] += r1[i][j - 1];
      r1[i][j] %= mod;
    }
  }
}
void candidates(int E) {
  for (int i = 0; i < K; i++) {
    for (int j = 0; j < K; j++)
      r2[i][j] = p[i][j];
  }
  if (E == 1) {
    for (int i = 0; i < K; i++) {
      for (int j = 0; j < K; j++)
        r2[i][j] = p[K - i - 1][j];
    }
  }
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < K; j++) {
      for (int k = 0; k < K; k++)
        r3[k][K - 1 - j] = r2[j][k];
    }
    long long Y = 0;
    for (int j = 0; j < K; j++) {
      for (int k = 0; k < K; k++) {
        r2[j][k] = r3[j][k];
        Y += r2[j][k] * power[j * W + k];
        Y %= mod;
      }
    }
    v.push_back(Y);
  }
}
long long modpow(long long a, long long b, long long m) {
  long long s1 = a, s2 = 1;
  for (int i = 0; i < 63; i++) {
    if ((b / (1LL << i)) % 2 == 1) {
      s2 *= s1;
      s2 %= m;
    }
    s1 *= s1;
    s1 %= m;
  }
  return s2;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % mod;
}
long long Hush(long long ax, long long ay, long long bx, long long by) {
  long long p1 = 0;
  if (ax >= 1 && ay >= 1)
    p1 = r1[ax - 1][ay - 1];
  long long p2 = r1[bx - 1][by - 1];
  long long p3 = 0;
  if (ax >= 1)
    p3 = r1[ax - 1][by - 1];
  long long p4 = 0;
  if (ay >= 1)
    p4 = r1[bx - 1][ay - 1];
  return (p1 + p2 - p3 - p4 + mod * 2) % mod;
}
int main() {
  while (true) {
    for (int i = 0; i < 1002; i++) {
      for (int j = 0; j < 1002; j++) {
        c[i][j] = 0;
        p[i][j] = 0;
        r1[i][j] = 0;
        r2[i][j] = 0;
        r3[i][j] = 0;
      }
    }
    v.clear();
    cin >> W >> H >> K;
    if (W == 0 && H == 0 && K == 0)
      break;
    for (int i = 0; i < H; i++) {
      string S;
      cin >> S;
      for (int j = 0; j < S.size(); j++) {
        int r = 63;
        if ('A' <= S[j] && S[j] <= 'Z')
          r = S[j] - 'A';
        if ('a' <= S[j] && S[j] <= 'z')
          r = S[j] - 'a' + 26;
        if ('0' <= S[j] && S[j] <= '9')
          r = S[j] - '0' + 52;
        if (S[j] == '+')
          r = 62;
        for (int k = 0; k < 6; k++) {
          c[i][j * 6 + (5 - k)] = (r / (1 << k)) % 2;
        }
      }
    }
    for (int i = 0; i < K; i++) {
      string S;
      cin >> S;
      for (int j = 0; j < S.size(); j++) {
        int r = 63;
        if ('A' <= S[j] && S[j] <= 'Z')
          r = S[j] - 'A';
        if ('a' <= S[j] && S[j] <= 'z')
          r = S[j] - 'a' + 26;
        if ('0' <= S[j] && S[j] <= '9')
          r = S[j] - '0' + 52;
        if (S[j] == '+')
          r = 62;
        for (int k = 0; k < 6; k++) {
          p[i][j * 6 + (5 - k)] = (r / (1 << k)) % 2;
        }
      }
    }
    makehush();
    candidates(0);
    candidates(1);
    int cnt = 0;
    for (int i = 0; i <= H - K; i++) {
      for (int j = 0; j <= W - K; j++) {
        bool OK = false;
        long long J = Hush(i, j, i + K, j + K);
        J = Div(J, power[i * W + j], mod);
        for (int k = 0; k < v.size(); k++) {
          if (J == v[k])
            OK = true;
        }
        if (OK == true)
          cnt++;
      }
    }
    cout << cnt << endl;
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
long long H, W, K, c[1002][1002], p[1002][1002], r1[1002][1002], r2[1002][1002],
    r3[1002][1002];
long long power[1000002], mod = 1000000007;
vector<long long> v;
void makehush() {
  power[0] = 1;
  for (int i = 1; i < H * W; i++) {
    power[i] = power[i - 1] * 2;
    power[i] %= mod;
  }
  for (int i = 0; i < H; i++) {
    for (int j = 0; j < W; j++) {
      r1[i][j] = c[i][j] * power[i * W + j];
    }
  }
  for (int i = 1; i < H; i++) {
    for (int j = 0; j < W; j++) {
      r1[i][j] += r1[i - 1][j];
      r1[i][j] %= mod;
    }
  }
  for (int i = 0; i < H; i++) {
    for (int j = 1; j < W; j++) {
      r1[i][j] += r1[i][j - 1];
      r1[i][j] %= mod;
    }
  }
}
void candidates(int E) {
  for (int i = 0; i < K; i++) {
    for (int j = 0; j < K; j++)
      r2[i][j] = p[i][j];
  }
  if (E == 1) {
    for (int i = 0; i < K; i++) {
      for (int j = 0; j < K; j++)
        r2[i][j] = p[K - i - 1][j];
    }
  }
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < K; j++) {
      for (int k = 0; k < K; k++)
        r3[k][K - 1 - j] = r2[j][k];
    }
    long long Y = 0;
    for (int j = 0; j < K; j++) {
      for (int k = 0; k < K; k++) {
        r2[j][k] = r3[j][k];
        Y += r2[j][k] * power[j * W + k];
        Y %= mod;
      }
    }
    v.push_back(Y);
  }
}
long long modpow(long long a, long long b, long long m) {
  long long s1 = a, s2 = 1;
  for (int i = 0; i < 35; i++) {
    if ((b / (1LL << i)) % 2 == 1) {
      s2 *= s1;
      s2 %= m;
    }
    s1 *= s1;
    s1 %= m;
  }
  return s2;
}
long long Div(long long a, long long b, long long m) {
  return (a * modpow(b, m - 2, m)) % mod;
}
long long Hush(long long ax, long long ay, long long bx, long long by) {
  long long p1 = 0;
  if (ax >= 1 && ay >= 1)
    p1 = r1[ax - 1][ay - 1];
  long long p2 = r1[bx - 1][by - 1];
  long long p3 = 0;
  if (ax >= 1)
    p3 = r1[ax - 1][by - 1];
  long long p4 = 0;
  if (ay >= 1)
    p4 = r1[bx - 1][ay - 1];
  return (p1 + p2 - p3 - p4 + mod * 2) % mod;
}
int main() {
  while (true) {
    for (int i = 0; i < 1002; i++) {
      for (int j = 0; j < 1002; j++) {
        c[i][j] = 0;
        p[i][j] = 0;
        r1[i][j] = 0;
        r2[i][j] = 0;
        r3[i][j] = 0;
      }
    }
    v.clear();
    cin >> W >> H >> K;
    if (W == 0 && H == 0 && K == 0)
      break;
    for (int i = 0; i < H; i++) {
      string S;
      cin >> S;
      for (int j = 0; j < S.size(); j++) {
        int r = 63;
        if ('A' <= S[j] && S[j] <= 'Z')
          r = S[j] - 'A';
        if ('a' <= S[j] && S[j] <= 'z')
          r = S[j] - 'a' + 26;
        if ('0' <= S[j] && S[j] <= '9')
          r = S[j] - '0' + 52;
        if (S[j] == '+')
          r = 62;
        for (int k = 0; k < 6; k++) {
          c[i][j * 6 + (5 - k)] = (r / (1 << k)) % 2;
        }
      }
    }
    for (int i = 0; i < K; i++) {
      string S;
      cin >> S;
      for (int j = 0; j < S.size(); j++) {
        int r = 63;
        if ('A' <= S[j] && S[j] <= 'Z')
          r = S[j] - 'A';
        if ('a' <= S[j] && S[j] <= 'z')
          r = S[j] - 'a' + 26;
        if ('0' <= S[j] && S[j] <= '9')
          r = S[j] - '0' + 52;
        if (S[j] == '+')
          r = 62;
        for (int k = 0; k < 6; k++) {
          p[i][j * 6 + (5 - k)] = (r / (1 << k)) % 2;
        }
      }
    }
    makehush();
    candidates(0);
    candidates(1);
    int cnt = 0;
    for (int i = 0; i <= H - K; i++) {
      for (int j = 0; j <= W - K; j++) {
        bool OK = false;
        long long J = Hush(i, j, i + K, j + K);
        J = Div(J, power[i * W + j], mod);
        for (int k = 0; k < v.size(); k++) {
          if (J == v[k])
            OK = true;
        }
        if (OK == true)
          cnt++;
      }
    }
    cout << cnt << endl;
  }
  return 0;
}