推荐博客 : https://blog.csdn.net/Whispers_zmf/article/details/80809609
http://www.cnblogs.com/Kv-Stalin/p/9443622.html
HDU 2222
const int maxn = 5e5+5;
int n;
char s[105];
int c[maxn][26];
int fail[maxn], val[maxn], last[maxn];
int rt = 0;
char p[maxn<<1];
void init(){
rt = 1;
memset(val, 0, sizeof(val));
memset(c, 0, sizeof(c));
}
void insert(){
int len = strlen(s+1);
int u = 0, v;
for(int i = 1; i <= len; i++){
v = s[i]-'a';
if (!c[u][v]) c[u][v] = rt++;
u = c[u][v];
}
val[u]++;
}
queue<int>que;
void build(){
while(!que.empty()) que.pop();
for(int i = 0; i < 26; i++){
if (c[0][i]) {
fail[c[0][i]] = 0;
que.push(c[0][i]);
}
}
while(!que.empty()){
int now = que.front(); que.pop();
for(int i = 0; i < 26; i++){
if (c[now][i]){
fail[c[now][i]] = c[fail[now]][i];
que.push(c[now][i]);
//last[now] = val[fail[now]]?fail[now]:last[fail[now]];
}
else c[now][i] = c[fail[now]][i];
}
}
}
int ans;
void query(){
int len = strlen(p+1);
int u = 0, v;
for(int i = 1; i <= len; i++){
v = p[i]-'a';
u = c[u][v];
for(int j = u; j && ~val[j]; j = fail[j]) {
ans += val[j];
val[j] = -1;
}
}
}
int main() {
int t;
cin >> t;
while(t--){
cin >> n;
init();
for(int i = 1; i <= n; i++){
scanf("%s", s+1);
insert();
}
build();
scanf("%s", p+1);
ans = 0;
query();
printf("%d
", ans);
}
return 0;
}