用的 Trie(不是 AC 自动机),TLE 两个点
下面的代码能够拿到除了 #10 #11 之外的全部测试点,正确性肯定有保障,目测复杂度似乎没有问题,可能问题就只有常数太大了,求卡常
#include <bits/stdc++.h>
using namespace std;
bitset<1 << 21> visited;
char s[1 << 21];
int n, m;
class Trie {
private:
typedef unsigned int size_T;
struct Node {
size_T end_count;
Node *sons[26];
Node() {
end_count = 0;
memset(sons, 0, sizeof(sons));
}
};
Node *root;
void dfs(size_T pos, const size_T &length, size_T &answer, const char *word) {
if (visited[pos] == true)
return;
visited[pos] = true;
answer = pos > answer ? pos : answer;
Node *current = root;
for (; pos < length; pos += 1) {
const size_T &Next = word[pos] - 'a';
if (current->sons[Next] == 0)
break;
current = current->sons[Next];
if (current->end_count)
dfs(pos + 1, length, answer, word);
}
}
public:
Trie() {
root = new Node;
}
void insert(const char *word) {
Node *current = root;
for (size_T i = 0; word[i]; i += 1) {
const size_T &Next = word[i] - 'a';
if (current->sons[Next] == 0)
current->sons[Next] = new Node;
current = current->sons[Next];
}
current->end_count += 1;
}
size_T get_endCount(const char *word) {
Node *current = root;
for (size_T i = 0; word[i]; i += 1) {
const size_T &Next = word[i] - 'a';
if (current->sons[Next] == 0)
return 0;
current = current->sons[Next];
}
return current->end_count;
}
size_T query(const char *word) {
size_T length = strlen(word), answer = 0;
visited.reset();
dfs(0, length, answer, word);
return answer;
}
} trie;
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> n >> m;
while (n--) {
cin >> s;
trie.insert(s);
}
while (m--) {
cin >> s;
cout << trie.query(s) << '\n';
}
return 0;
}