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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_set>
#include <valarray>
#include <vector>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define REP(i, x) for (int i = 0; i < (int)(x); i++)
#define REPS(i, x) for (int i = 1; i <= (int)(x); i++)
#define RREP(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define RREPS(i, x) for (int i = ((int)(x)); i > 0; i--)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define RFOR(i, c)                                                             \\
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a, b) make_pair(a, b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "[";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "]";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &t) {
  os << "{";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
template <class S, class T>
pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first + t.first, s.second + t.second);
}
template <class S, class T>
pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first - t.first, s.second - t.second);
}

const int INF = 1 << 28;
const double EPS = 1e-8;
const int MOD = 1000000007;

struct AhoCorasick {
  struct State {
    int next[256], failure;
    int accepts;
    State() : failure(0), accepts(0) { memset(next, 0, sizeof(next)); }
  };
  vector<State> states;
  int pats;

  AhoCorasick() {}
  AhoCorasick(vector<string> patterns) : states(1), pats(patterns.size()) {
    REP(i, pats) { // make trie
      int p = 0;
      FOR(c, patterns[i]) {
        if (states[p].next[*c] <= 0) {
          states[p].next[*c] = states.size();
          states.emplace_back();
        }
        p = states[p].next[*c];
      }
      states[p].accepts |= 1 << i;
    }

    queue<int> q; // make failure link
    q.push(0);
    while (!q.empty()) {
      const int p = q.front();
      q.pop();
      REP(i, 256) {
        const int dst = states[p].next[i];
        if (!dst) {
          // 大量に呼び出す時はnextを全部埋めとくといい
          int q = p;
          while (q && !states[q].next[i])
            q = states[q].failure;
          states[p].next[i] = states[q].next[i];
        } else {
          q.push(dst);
          int f = states[p].failure;
          while (f && states[f].next[i] <= 0)
            f = states[f].failure;
          if (p) {
            states[dst].failure = states[f].next[i];
            states[dst].accepts |= states[states[f].next[i]].accepts;
          }
        }
      }
    }
  }

  int go_next(int p, const int &c) {
    // nextが埋まってるならここはいらない
    // while(p && !states[p].next[c]) p = states[p].failure;
    return states[p].next[c];
  }
  pair<int, int> apply(string s, int p = 0) {
    int res = 0;
    REP(i, s.size()) {
      p = go_next(p, s[i]);
      res |= states[p].accepts;
    }
    return make_pair(p, res);
  }
  pair<int, int> apply(char c, int p = 0) {
    int res = 0;
    p = go_next(p, c);
    res |= states[p].accepts;
    return make_pair(p, res);
  }
} ac;
int d, n, m, ansn;
string s;
unordered_set<ull> hashes;
priority_queue<string> ans;

const string db = ".ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void dfs(string &t, int i, int p, ull rh, int last, int d) {
  if (d < 0 || i > s.size() || last + m <= t.size())
    return;
  if (i == s.size()) {
    if (last == t.size() && hashes.find(rh) == hashes.end()) {
      hashes.insert(rh);
      ans.push(t);
      ansn++;
      if (ans.size() > 5)
        ans.pop();
    }
  }
  if (d) {
    dfs(t, i + 1, p, rh, last, d - 1); // delete
    FOR(c, db) {
      t.push_back(*c);
      pii res = ac.apply(*c, p);
      dfs(t, i, res.first, rh * MOD + *c, res.second ? t.size() : last,
          d - 1); // insert
      if (s[i] != *c)
        dfs(t, i + 1, res.first, rh * MOD + *c, res.second ? t.size() : last,
            d - 1); // modify
      t.resize(t.size() - 1);
    }
  }
  t.push_back(s[i]);
  pii res = ac.apply(s[i], p);
  dfs(t, i + 1, res.first, rh * MOD + s[i], res.second ? t.size() : last, d);
  t.resize(t.size() - 1);
}

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  while (cin >> d >> n, n) {
    cin >> s;
    vector<string> t(n);
    REP(i, n) cin >> t[i];
    m = t[0].size();
    ac = AhoCorasick(t);
    ansn = 0;
    string tmp = "";
    dfs(tmp, 0, 0, 0, 0, d);
    cout << ansn << endl;
    if (ansn <= 5) {
      vector<string> ss;
      REP(i, ansn) {
        ss.push_back(ans.top());
        ans.pop();
      }
      RREP(i, ansn) cout << ss[i] << endl;
    }
    while (!ans.empty())
      ans.pop();
    hashes.clear();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_set>
#include <valarray>
#include <vector>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define REP(i, x) for (int i = 0; i < (int)(x); i++)
#define REPS(i, x) for (int i = 1; i <= (int)(x); i++)
#define RREP(i, x) for (int i = ((int)(x)-1); i >= 0; i--)
#define RREPS(i, x) for (int i = ((int)(x)); i > 0; i--)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define RFOR(i, c)                                                             \\
  for (__typeof((c).rbegin()) i = (c).rbegin(); i != (c).rend(); i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a, b) make_pair(a, b)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &t) {
  os << "[";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "]";
  return os;
}
template <class T> ostream &operator<<(ostream &os, const set<T> &t) {
  os << "{";
  FOR(it, t) {
    if (it != t.begin())
      os << ",";
    os << *it;
  }
  os << "}";
  return os;
}
template <class S, class T>
ostream &operator<<(ostream &os, const pair<S, T> &t) {
  return os << "(" << t.first << "," << t.second << ")";
}
template <class S, class T>
pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first + t.first, s.second + t.second);
}
template <class S, class T>
pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) {
  return pair<S, T>(s.first - t.first, s.second - t.second);
}

const int INF = 1 << 28;
const double EPS = 1e-8;
const int MOD = 1000000007;

struct AhoCorasick {
  struct State {
    int next[256], failure;
    int accepts;
    State() : failure(0) { memset(next, 0, sizeof(next)); }
  };
  vector<State> states;
  int pats;

  AhoCorasick() {}
  AhoCorasick(vector<string> patterns) : states(1), pats(patterns.size()) {
    REP(i, pats) { // make trie
      int p = 0;
      FOR(c, patterns[i]) {
        if (states[p].next[*c] <= 0) {
          states[p].next[*c] = states.size();
          states.emplace_back();
        }
        p = states[p].next[*c];
      }
      states[p].accepts |= 1 << i;
    }

    queue<int> q; // make failure link
    q.push(0);
    while (!q.empty()) {
      const int p = q.front();
      q.pop();
      REP(i, 256) {
        const int dst = states[p].next[i];
        if (!dst) {
          // 大量に呼び出す時はnextを全部埋めとくといい
          int q = p;
          while (q && !states[q].next[i])
            q = states[q].failure;
          states[p].next[i] = states[q].next[i];
        } else {
          q.push(dst);
          int f = states[p].failure;
          while (f && states[f].next[i] <= 0)
            f = states[f].failure;
          if (p) {
            states[dst].failure = states[f].next[i];
            states[dst].accepts |= states[states[f].next[i]].accepts;
          }
        }
      }
    }
  }

  int go_next(int p, const int &c) {
    // nextが埋まってるならここはいらない
    // while(p && !states[p].next[c]) p = states[p].failure;
    return states[p].next[c];
  }
  pair<int, int> apply(string s, int p = 0) {
    int res = 0;
    REP(i, s.size()) {
      p = go_next(p, s[i]);
      res |= states[p].accepts;
    }
    return make_pair(p, res);
  }
  pair<int, int> apply(char c, int p = 0) {
    int res = 0;
    p = go_next(p, c);
    res |= states[p].accepts;
    return make_pair(p, res);
  }
} ac;
int d, n, m, ansn;
string s;
unordered_set<ull> hashes;
priority_queue<string> ans;

string db = ".ABCDEFGHIJKLMNOPQRSTUVWXYZ";

void dfs(string &t, int i, int p, ull rh, int last, int d) {
  if (d < 0 || i > s.size() || last + m <= t.size())
    return;
  if (i == s.size()) {
    if (last == t.size() && hashes.find(rh) == hashes.end()) {
      hashes.insert(rh);
      ans.push(t);
      ansn++;
      if (ans.size() > 5)
        ans.pop();
    }
  }
  if (d) {
    dfs(t, i + 1, p, rh, last, d - 1); // delete
    FOR(c, db) {
      t.push_back(*c);
      pii res = ac.apply(*c, p);
      dfs(t, i, res.first, rh * MOD + *c, res.second ? t.size() : last,
          d - 1); // insert
      if (s[i] != *c)
        dfs(t, i + 1, res.first, rh * MOD + *c, res.second ? t.size() : last,
            d - 1); // modify
      t.resize(t.size() - 1);
    }
  }
  t.push_back(s[i]);
  pii res = ac.apply(s[i], p);
  dfs(t, i + 1, res.first, rh * MOD + s[i], res.second ? t.size() : last, d);
  t.resize(t.size() - 1);
}

int main(int argc, char *argv[]) {
  ios::sync_with_stdio(false);
  while (cin >> d >> n, n) {
    cin >> s;
    vector<string> t(n);
    REP(i, n) cin >> t[i];
    m = t[0].size();
    ac = AhoCorasick(t);
    ansn = 0;
    string tmp = "";
    dfs(tmp, 0, 0, 0, 0, d);
    cout << ansn << endl;
    if (ansn <= 5) {
      vector<string> ss;
      REP(i, ansn) {
        ss.push_back(ans.top());
        ans.pop();
      }
      RREP(i, ansn) cout << ss[i] << endl;
    }
    while (!ans.empty())
      ans.pop();
    hashes.clear();
  }
  return 0;
}