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

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

vector<int> edge[5001];

bool same(string a, string b, int len, int v) {
  if (a.size() < len || b.size() < len + v)
    return false;
  a = a.substr(0, v);
  b = b.substr(len, v);
  return (a == b);
}

void KMP(string text, string pattern, int v) {
  int textN = text.size();
  int patternN = pattern.size();
  vector<int> next(patternN + 1, 0);
  next[0] = 1;
  for (int i = 1; i <= patternN; i++) {
    string s = pattern.substr(0, i);
    int len = 1;
    while (i - len > 0 && !same(s, pattern, len, i - len))
      len++;
    next[i] = len;
  }
  int cnt = 0;
  int tp = 0, pp = 0;
  while (tp < textN) {
    if (text[tp] == pattern[pp]) {
      tp++;
      pp++;
    } else {
      pp -= next[pp];
      if (pp < 0) {
        tp++;
        pp++;
      }
    }
    if (pp == patternN) {
      edge[tp - pattern.size()].push_back(v);
    }
  }
}

int n, m;
string e[13];
string text;
bool dp[5001][1 << 12];

int main(void) {
  while (1) {
    scanf("%d%d", &n, &m);
    if (n == 0 && m == 0)
      break;
    for (int i = 0; i < n; i++) {
      cin >> e[i];
    }
    text = "";
    for (int i = 0; i < m; i++) {
      string str;
      cin >> str;
      text += str;
    }
    int len = text.size();
    for (int i = 0; i < len; i++) {
      edge[i].clear();
    }
    for (int i = 0; i < n; i++) {
      KMP(text, e[i], i);
    }
    memset(dp, false, sizeof(dp));
    ll res = 0;
    for (int i = 0; i < (1 << n); i++) {
      for (int j = 0; j <= len; j++) {
        if (i == 0)
          dp[j][i] = true;
        if (!dp[j][i])
          continue;
        if (i == ((1 << n) - 1)) {
          res += dp[j][i] ? 1 : 0;
        }
        for (int l = 0; l < edge[j].size(); l++) {
          int k = edge[j][l];
          if ((!((i >> k) & 1))) {
            dp[j + e[k].size()][i | (1 << k)] |= dp[j][i];
          }
        }
      }
    }
    printf("%lld\\n", res);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define MOD 1000000007LL
using namespace std;

typedef long long ll;
typedef pair<int, int> P;

vector<int> edge[5001];

bool same(string a, string b, int len, int v) {
  if (a.size() < len || b.size() < len + v)
    return false;
  a = a.substr(0, v);
  b = b.substr(len, v);
  return (a == b);
}

void KMP(string text, string pattern, int v) {
  int textN = text.size();
  int patternN = pattern.size();
  vector<int> next(patternN + 1, 0);
  next[0] = 1;
  for (int i = 1; i <= patternN; i++) {
    string s = pattern.substr(0, i);
    int len = 1;
    while (i - len > 0 && !same(s, pattern, len, i - len))
      len++;
    next[i] = len;
  }
  int cnt = 0;
  int tp = 0, pp = 0;
  while (tp < textN) {
    if (text[tp] == pattern[pp]) {
      tp++;
      pp++;
    } else {
      pp -= next[pp];
      if (pp < 0) {
        tp++;
        pp++;
      }
    }
    if (pp == patternN) {
      edge[tp - pattern.size()].push_back(v);
    }
  }
}

int n, m;
string e[13];
string text;
bool dp[5001][1 << 12];

int main(void) {
  while (1) {
    scanf("%d%d", &n, &m);
    if (n == 0 && m == 0)
      break;
    for (int i = 0; i < n; i++) {
      cin >> e[i];
    }
    text = "";
    for (int i = 0; i < m; i++) {
      string str;
      cin >> str;
      text += str;
    }
    int len = text.size();
    for (int i = 0; i < len; i++) {
      edge[i].clear();
    }
    for (int i = 0; i < n; i++) {
      KMP(text, e[i], i);
    }
    memset(dp, false, sizeof(dp));
    ll res = 0;
    for (int i = 0; i < (1 << n); i++) {
      for (int j = 0; j <= len; j++) {
        if (i == 0)
          dp[j][i] = true;
        if (i == ((1 << n) - 1)) {
          res += dp[j][i] ? 1 : 0;
        }
        for (int l = 0; l < edge[j].size(); l++) {
          int k = edge[j][l];
          if ((!((i >> k) & 1))) {
            dp[j + e[k].size()][i | (1 << k)] |= dp[j][i];
          }
        }
      }
    }
    printf("%lld\\n", res);
  }
  return 0;
}