232-aka-pretty-pi 2024. 7. 26. 08:49
template <typename C, typename Cmp = std::equal_to<>>
std::vector<int> getZ(const C& cont, Cmp&& cmp = Cmp {}) {
  assert(!cont.empty() && "at function \"getZ\"");
  int n = int(cont.size());
  std::vector<int> z(n);
  int opt = 0;
  for (int i = 1; i < n; ++i) {
    if (opt + z[opt] > i) {
      z[i] = std::min(opt + z[opt] - i, z[i - opt]);
    }
    while (i + z[i] < n && cmp(cont[z[i]], cont[i + z[i]])) {
      z[i] += 1;
    }
    if (opt + z[opt] < i + z[i]) {
      opt = i;
    }
  }
  z[0] = n;
  return z;
}