传送门
这一题实际上就是多模式,多文本的匹配,对于这道题来说,用AC自动机就可以解决,题解同前一道题。
代码:
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 10005
#define MAXC 128
#define MAXM 505
#define MAXL 205
int n, root, sz, q[MAXM*MAXL];
vector<int> arr;
char s[MAXN];
struct Trie {
int nxt[MAXC], fail, id;
} t[MAXM * MAXL];
inline int NewNode() {
return ++ sz;
}
inline void Ins(char *s, int id) {
int len = strlen(s), cur = root;
for(int i = 0; i < len; ++ i) {
if(!t[cur].nxt[s[i]]) t[cur].nxt[s[i]] = NewNode();
cur = t[cur].nxt[s[i]];
}
t[cur].id = id;
}
inline void Build() {
int l = 1, r = 0; t[root].id = -1;
for(int i = 0; i < MAXC; ++ i)
if(!t[root].nxt[i]) t[root].nxt[i] = root;
else {
t[ t[root].nxt[i] ].fail = root;
q[++ r] = t[root].nxt[i];
}
while(l <= r) {
int u = q[l ++];
for(int i = 0; i < MAXC; ++ i)
if(!t[u].nxt[i]) t[u].nxt[i] = t[ t[u].fail ].nxt[i];
else {
t[ t[u].nxt[i] ].fail = t[ t[u].fail ].nxt[i];
q[++ r] = t[u].nxt[i];
}
}
}
inline int Query(char *s) {
int len = strlen(s), cur = root, ans = 0;
for(int i = 0; i < len; ++ i) {
cur = t[cur].nxt[s[i]];
int tmp = cur;
while(~t[tmp].id) {
if(t[tmp].id) arr.push_back(t[tmp].id);
tmp = t[tmp].fail;
}
}
return ans;
}
int main() {
sz = 0; root = NewNode();
scanf("%d", &n);
for(int i = 1; i <= n; ++ i) {
scanf("%s", s);
Ins(s, i);
}
Build(); int Count = 0;
scanf("%d", &n);
for(int i = 1; i <= n; ++ i) {
scanf("%s", s);
Query(s);
if(arr.size()) {
++ Count;
sort(arr.begin(), arr.end());
printf("web %d:", i);
for(int j = 0; j < (int)arr.size(); ++ j)
printf(" %d", arr[j]);
putchar('\n');
arr.clear();
}
}
printf("total: %d\n", Count);
return 0;
}