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

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define uint unsigned int
#define dotimes(i, n) for (int i = 0, i##max__ = (n); i < i##max__; i++)
#define whole(x, f, ...)                                                       \\
  ([&](decltype((x)) c) { return (f)(begin(c), end(c), ##__VA_ARGS__); })(x)

int rint() {
  int x;
  scanf("%lld", &x);
  return x;
}
void wint(int x) { printf("%lld\\n", x); }

template <typename T> int size(T const &c) {
  return static_cast<int>(c.size());
}
template <typename T> bool maxs(T &a, T const &b) {
  return a < b ? a = b, true : false;
}
template <typename T> bool mins(T &a, T const &b) {
  return a > b ? a = b, true : false;
}
inline int lg(int x) {
  return 63 - __builtin_clzll(static_cast<unsigned int>(x));
}

#ifdef EBUG
#define INT_WIDTH ""
#include "debug.h"
#else
#define inspect(...)                                                           \\
  do {                                                                         \\
  } while (0)
#define debugf(...)                                                            \\
  do {                                                                         \\
  } while (0)
#define debugv(...)                                                            \\
  do {                                                                         \\
  } while (0)
#endif

template <typename RandomAccessIterator>
vector<int> z_algorithm(const RandomAccessIterator first,
                        const RandomAccessIterator last) {
  const int n = last - first;
  vector<int> Z(n);
  for (int l = 0, r = 0, k = 1; k < n; k++) {
    if (k >= r) {
      int j = 0;
      while (j < n - k && *(first + j) == *(first + k + j))
        j++;
      Z[k] = j;
      if (j) {
        l = k;
        r = k + j;
      }
    } else {
      int i = k - l, j = r - k;
      if (Z[i] < j)
        Z[k] = Z[i];
      else {
        while (j < n - k && *(first + j) == *(first + k + j))
          j++;
        Z[k] = j;
        l = k;
        r = k + j;
      }
    }
  }
  return Z;
}

template <typename RandomAccessIterator> class KMP {
  RandomAccessIterator p;
  vector<int> A;

public:
  KMP(const RandomAccessIterator p_first, const RandomAccessIterator p_last)
      : p(p_first) {
    vector<int> Z = z_algorithm(p_first, p_last);
    A.resize(Z.size() + 1);
    dotimes(i, Z.size()) if (Z[i] && !A[i + Z[i]]) A[i + Z[i]] = Z[i];
  }
  template <typename ForwardIterator, typename F>
  void search(const ForwardIterator s_first, const ForwardIterator s_last,
              F f) {
    int i = 0, j = 0, m = ::size(A) - 1;
    for (ForwardIterator s = s_first; s != s_last;)
      if (*s == *(p + j)) {
        ++s;
        i++;
        j++;
        if (j == m) {
          f(i - j);
          j = A[j];
        }
      } else if (j)
        j = A[j];
      else {
        ++s;
        i++;
      }
  }
};

signed main() {
  char T[1'000'001], P[10'001];
  scanf("%s\\n%s\\n", T, P);
  int n = strlen(T), m = strlen(P);
  if (n < m)
    return 0;
  KMP<char *> kmp(P, P + m);
  kmp.search(T, T + n, wint);
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>

static const size_t T_MAX = 1000000, P_MAX = 10000, N = 10 + 26 + 26;
static const int sentinel = N + 1;
char T[T_MAX], P[P_MAX];
static size_t L[P_MAX][N];

static int consume() {
  auto c = getchar();
  if ('0' <= c && c <= '9')
    return c - '0';
  if ('A' <= c && c <= 'Z')
    return 10 + (c - 'A');
  if ('a' <= c && c <= 'z')
    return 36 + (c - 'a');
  return sentinel;
}

int main() {
  size_t m = 0, n = 0;
  for (;;) {
    auto c = consume();
    if (c == sentinel)
      break;
    T[m++] = c;
  }
  for (;;) {
    auto c = consume();
    if (c == sentinel)
      break;
    P[n++] = c;
  }
  size_t l[N];
  std::fill(l, l + N, size_t(-1));
  for (size_t i = 0; i < n; i++) {
    for (size_t j = 0; j < N; j++)
      L[i][j] = l[j] == size_t(-1) ? i + 1 : i - l[j];
    l[int(P[i])] = i;
  }
  for (size_t i = n - 1; i < m;)
    for (size_t j = 0;; j++) {
      if (j == n) {
        printf("%zu\\n", i + 1 - n);
        i += L[n - 1][int(T[i])];
        break;
      }
      if (P[n - 1 - j] != T[i - j]) {
        i += L[n - 1 - j][int(T[i - j])];
        break;
      }
    }
  return 0;
}