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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
ld eps = 1e-9;

vector<vector<int>> mirror(vector<vector<int>> from) {
  vector<vector<int>> to(from.size(), vector<int>(from[0].size()));
  for (int i = 0; i < from.size(); ++i) {
    for (int j = 0; j < from[i].size(); ++j) {
      to[i][from[i].size() - j - 1] = from[i][j];
    }
  }
  return to;
}
vector<vector<int>> rotate(vector<vector<int>> from) {
  vector<vector<int>> to(from[0].size(), vector<int>(from.size()));
  for (int i = 0; i < from.size(); ++i) {
    for (int j = 0; j < from[i].size(); ++j) {
      to[j][from.size() - i - 1] = from[i][j];
    }
  }
  return to;
}

struct RollingHash {
  static const int mul0 = 7, mul1 = 11;
  static const int add0 = 23, add1 = 29;
  size_t len;
  vector<int> hash_, hash2_;
  static vector<int> pmo_, pmo2_;
  void init(vector<int> s) {
    len = s.size();
    hash_.resize(len + 1);
    hash2_.resize(len + 1);

    hash_[0] = 0;
    hash2_[0] = 0;

    if (pmo_.empty()) {
      pmo_.push_back(1), pmo2_.push_back(1);
    }
    while (pmo_.size() <= len) {
      pmo_.push_back(pmo_.back() * mul0);
      pmo2_.push_back(pmo2_.back() * mul1);
    }
    for (unsigned int i = 0; i < len; ++i) {
      hash_[i + 1] = (hash_[i] * mul0 + s[i]);
      hash2_[i + 1] = (hash2_[i] * mul1 + s[i]);
    }
  }
  void init(string s) {
    len = s.size();
    hash_.resize(len + 1);
    hash2_.resize(len + 1);

    hash_[0] = 0;
    hash2_[0] = 0;

    if (pmo_.empty()) {
      pmo_.push_back(1), pmo2_.push_back(1);
    }
    while (pmo_.size() <= len) {
      pmo_.push_back(pmo_.back() * mul0);
      pmo2_.push_back(pmo2_.back() * mul1);
    }
    for (unsigned int i = 0; i < len; ++i) {
      hash_[i + 1] = (hash_[i] * mul0 + s[i]);
      hash2_[i + 1] = (hash2_[i] * mul1 + s[i]);
    }
  }
  pair<int, int> hash(int l, int r) { // s[l..r]
    return make_pair(hash_[r + 1] - hash_[l] * pmo_[r + 1 - l],
                     hash2_[r + 1] - hash2_[l] * pmo2_[r + 1 - l]);
  }
  pair<int, int> hash() { // s[all]
    return hash(0, len - 1);
  }

  // hash????????????
  static pair<int, int> concat(pair<int, int> L, pair<int, int> R,
                               int RLength) { // hash(L+R)
    return make_pair((R.first + L.first * pmo_[RLength]),
                     (R.second + L.second * pmo2_[RLength]));
  }
};
vector<int> RollingHash::pmo_;
vector<int> RollingHash::pmo2_;
int main() {
  map<char, int> mp;
  for (int i = 0; i < 26; ++i) {
    mp['a' + i] = 26 + i;
    mp['A' + i] = i;
  }
  for (int i = 1; i <= 9; ++i) {
    mp['0' + i] = 52 + i;
  }
  mp['0'] = 52;
  mp['+'] = 62;
  mp['/'] = 63;
  while (1) {
    int W, H, Q;
    cin >> W >> H >> Q;
    if (!W)
      break;
    vector<vector<int>> fields(H);
    for (int i = 0; i < H; ++i) {
      string st;
      cin >> st;
      int rest = W;
      for (int j = 0; j < st.size(); ++j) {
        bitset<6> bs(mp[st[j]]);
        for (int k = 0; k < 6; ++k) {
          if (rest) {

            fields[i].push_back(bs[5 - k]);
            rest--;
          }
        }
      }
    }
    vector<vector<int>> wally(Q);
    for (int i = 0; i < Q; ++i) {
      string st;
      cin >> st;
      int rest = Q;
      for (int j = 0; j < st.size(); ++j) {
        bitset<6> bs(mp[st[j]]);

        for (int k = 0; k < 6; ++k) {
          if (rest) {

            wally[i].push_back(bs[5 - k]);
            rest--;
          }
        }
      }
      wally[i].resize(Q);
    }
    set<vector<vector<int>>> wallys;

    for (int i = 0; i < 4; ++i) {
      wallys.emplace(wally);
      wallys.emplace(mirror(wally));
      wally = rotate(wally);
    }
    vector<RollingHash> firhs(H);
    for (int i = 0; i < H; ++i) {
      firhs[i].init(fields[i]);
    }
    int ans = 0;
    vector<vector<int>> memo(H, vector<int>(W, -1));
    for (const auto w : wallys) {
      vector<RollingHash> warhs(w.size());
      for (int i = 0; i < w.size(); ++i) {
        warhs[i].init(w[i]);
      }
      for (int l = 0; l < int(fields[0].size()) - int(w[0].size()) + 1; ++l) {
        const int r = l + w[0].size() - 1;
        for (int u = 0; u < int(fields.size()) - int(w.size()) + 1; u++) {
          const int d = u + w.size() - 1;
          bool ok = true;

          for (size_t y = u; y <= d; y++) {
            if (firhs[y].hash(l, r) != warhs[y - u].hash()) {
              ok = false;
              break;
            }
          }

          if (ok)
            ans++;
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
ld eps = 1e-9;

vector<vector<int>> mirror(vector<vector<int>> from) {
  vector<vector<int>> to(from.size(), vector<int>(from[0].size()));
  for (int i = 0; i < from.size(); ++i) {
    for (int j = 0; j < from[i].size(); ++j) {
      to[i][from[i].size() - j - 1] = from[i][j];
    }
  }
  return to;
}
vector<vector<int>> rotate(vector<vector<int>> from) {
  vector<vector<int>> to(from[0].size(), vector<int>(from.size()));
  for (int i = 0; i < from.size(); ++i) {
    for (int j = 0; j < from[i].size(); ++j) {
      to[j][from.size() - i - 1] = from[i][j];
    }
  }
  return to;
}

struct RollingHash {
  static const int mul0 = 7, mul1 = 11;
  static const int add0 = 23, add1 = 29;
  size_t len;
  vector<int> hash_, hash2_;
  static vector<int> pmo_, pmo2_;
  void init(vector<int> s) {
    len = s.size();
    hash_.resize(len + 1);
    hash2_.resize(len + 1);

    hash_[0] = 0;
    hash2_[0] = 0;

    if (pmo_.empty()) {
      pmo_.push_back(1), pmo2_.push_back(1);
    }
    while (pmo_.size() <= len) {
      pmo_.push_back(pmo_.back() * mul0);
      pmo2_.push_back(pmo2_.back() * mul1);
    }
    for (unsigned int i = 0; i < len; ++i) {
      hash_[i + 1] = (hash_[i] * mul0 + s[i]);
      hash2_[i + 1] = (hash2_[i] * mul1 + s[i]);
    }
  }
  void init(string s) {
    len = s.size();
    hash_.resize(len + 1);
    hash2_.resize(len + 1);

    hash_[0] = 0;
    hash2_[0] = 0;

    if (pmo_.empty()) {
      pmo_.push_back(1), pmo2_.push_back(1);
    }
    while (pmo_.size() <= len) {
      pmo_.push_back(pmo_.back() * mul0);
      pmo2_.push_back(pmo2_.back() * mul1);
    }
    for (unsigned int i = 0; i < len; ++i) {
      hash_[i + 1] = (hash_[i] * mul0 + s[i]);
      hash2_[i + 1] = (hash2_[i] * mul1 + s[i]);
    }
  }
  pair<int, int> hash(int l, int r) { // s[l..r]
    return make_pair(hash_[r + 1] - hash_[l] * pmo_[r + 1 - l],
                     hash2_[r + 1] - hash2_[l] * pmo2_[r + 1 - l]);
  }
  pair<int, int> hash() { // s[all]
    return hash(0, len - 1);
  }

  // hash????????????
  static pair<int, int> concat(pair<int, int> L, pair<int, int> R,
                               int RLength) { // hash(L+R)
    return make_pair((R.first + L.first * pmo_[RLength]),
                     (R.second + L.second * pmo2_[RLength]));
  }
};
vector<int> RollingHash::pmo_;
vector<int> RollingHash::pmo2_;
int main() {
  map<char, int> mp;
  for (int i = 0; i < 26; ++i) {
    mp['a' + i] = 26 + i;
    mp['A' + i] = i;
  }
  for (int i = 1; i <= 9; ++i) {
    mp['0' + i] = 52 + i;
  }
  mp['0'] = 52;
  mp['+'] = 62;
  mp['/'] = 63;
  while (1) {
    int W, H, Q;
    cin >> W >> H >> Q;
    if (!W)
      break;
    vector<vector<int>> fields(H);
    for (int i = 0; i < H; ++i) {
      string st;
      cin >> st;
      for (int j = 0; j < st.size(); ++j) {
        bitset<6> bs(mp[st[j]]);
        for (int k = 0; k < 6; ++k) {
          fields[i].push_back(bs[5 - k]);
        }
      }
    }
    vector<vector<int>> wally(Q);
    for (int i = 0; i < Q; ++i) {
      string st;
      cin >> st;
      int rest = Q;
      for (int j = 0; j < st.size(); ++j) {
        bitset<6> bs(mp[st[j]]);

        for (int k = 0; k < 6; ++k) {
          if (rest) {

            wally[i].push_back(bs[5 - k]);
            rest--;
          }
        }
      }
      wally[i].resize(Q);
    }
    set<vector<vector<int>>> wallys;

    for (int i = 0; i < 4; ++i) {
      wallys.emplace(wally);
      wallys.emplace(mirror(wally));
      wally = rotate(wally);
    }
    vector<RollingHash> firhs(H);
    for (int i = 0; i < H; ++i) {
      firhs[i].init(fields[i]);
    }
    int ans = 0;
    for (const auto w : wallys) {
      vector<RollingHash> warhs(w.size());
      for (int i = 0; i < w.size(); ++i) {
        warhs[i].init(w[i]);
      }
      for (int l = 0; l < int(fields[0].size()) - int(w[0].size()) + 1; ++l) {
        const int r = l + w[0].size() - 1;
        for (int u = 0; u < int(fields.size()) - int(w.size()) + 1; u++) {
          const int d = u + w.size() - 1;
          bool ok = true;
          for (size_t y = u; y <= d; y++) {
            if (firhs[y].hash(l, r) != warhs[y - u].hash())
              ok = false;
          }
          if (ok)
            ans++;
        }
      }
    }
    cout << ans << endl;
  }
  return 0;
}