/****************************************************************************************************
改了下HDU2222的代码,今天才知道原来可见的ASCII码是128个,害得我MLE了一次~
****************************************************************************************************/
#include <iostream>
#include <functional>
#include <algorithm>
//#include <hash_map> //Visual C++ lib
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define LOWBIT(x) ( (x) & ( (x) ^ ( (x) - 1 ) ) )
#define CLR(x, k) memset((x), (k), sizeof(x))
#define CPY(t, s) memcpy((t), (s), sizeof(s))
#define LEN(s) static_cast<int>( strlen((s)) )
typedef long long LL; //GNU C++
typedef unsigned long long ULL;
//typedef __int64 LL; //Visual C++ 2010
//typedef unsigned __int64 ULL;
typedef double LF;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<double, double> PDD;
//typedef hash_map<int, int>::iterator HMI;
typedef map<int, int>::iterator MI;
typedef vector<int>::iterator VI;
typedef list<int>::iterator LI;
typedef set<int>::iterator SI;
const int INF_INT = 0x3f3f3f3f;
const LL INF_LL = 0x7fffffffffffffffLL; //15f
const double oo = 10e9;
const double eps = 10e-9;
const double PI = acos(-1.0);
const int MAXN = 100004;
const int MAXM = 10004;
const int MAXC = 128;
int n, m;
char str[MAXM];
struct Node
{
Node *next[MAXC];
Node *fail;
int cnt;
}trie[MAXN], *root;
int ncnt;
queue<Node *>Q;
void initTrie()
{
root = trie;
ncnt = 1;
for (int i = 0; i < MAXC; ++i)
{
root->next[i] = NULL;
}
root->fail = NULL;
root->cnt = 0;
return ;
}
Node* createNode(Node *crt)
{
for (int i = 0; i < MAXC; ++i)
{
crt->next[i] = NULL;
}
crt->fail = NULL;
crt->cnt = 0;
return crt;
}
void insert(char *ch, int id)
{
Node *ptr = root;
int nxt;
while (*ch != '\0')
{
//nxt = *ch - 'a';
nxt = *ch;
if (NULL == ptr->next[nxt])
{
ptr->next[nxt] = createNode( &trie[ncnt++] );
}
ptr = ptr->next[nxt];
++ch;
}
ptr->cnt = id;
return ;
}
void buildAC_automation()
{
while (!Q.empty())
{
Q.pop();
}
Q.push(root);
Node *crt, *nxt, *ptr;
while (!Q.empty())
{
crt = Q.front();
Q.pop();
for (int i = 0; i < MAXC; ++i)
{
nxt = crt->next[i];
if (nxt != NULL)
{
for (ptr = crt->fail; ptr != NULL; ptr = ptr->fail)
{
if (ptr->next[i] != NULL)
{
nxt->fail = ptr->next[i];
//nxt->cnt += nxt->fail->cnt; //
break ;
}
}
if (NULL == ptr)
{
nxt->fail = root;
}
Q.push(nxt);
}
else
{
if (root == crt)
{
crt->next[i] = root;
}
else
{
crt->next[i] = crt->fail->next[i];
}
}
}
}
return ;
}
bool query(char *str, int rk)
{
int id, top = 0, S[105];
Node *ptr = root, *ptt;
while (*str != '\0' && top < 3)
{
//id = *str - 'a';
id = *str;
ptr = ptr->next[id];
/*for (ptt = ptr; ptt != NULL && ptt->cnt != -1; ptt = ptt->fail)
{
res += ptt->cnt;
ptt->cnt = -1;
}*/
for (ptt = ptr; ptt != NULL && ptt->cnt != 0; ptt = ptt->fail)
{
S[top++] = ptt->cnt;
}
++str;
}
if (!top)
{
return false;
}
sort(S, S + top);
printf("web %d:", rk);
for (int i = 0; i < top; ++i)
{
printf(" %d", S[i]);
}
puts("");
return true;
}
void ace()
{
int res;
char ch[202];
while (scanf("%d%*c", &n) != EOF)
{
initTrie();
for (int i = 1; i <= n; ++i)
{
gets(ch);
insert(ch, i);
}
buildAC_automation();
res = 0;
scanf("%d%*c", &m);
for (int i = 1; i <= m; ++i)
{
gets(str);
res += query(str, i);
}
printf("total: %d\n", res);
}
return ;
}
int main()
{
ace();
return 0;
}