//静态
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#define N 10010
#define WORD_SIZE 128
#define WORD_START 0
using namespace std;
class Node
{
public :
int next[WORD_SIZE];
int count;
int fail;
};
class AC_automation
{
public :
Node tree[N];
int cur_id;
int q[N];
int root;
AC_automation()
{
cur_id = 0;
root = 0;
init_node(root);
}
void insert_word( char *str, int id );
void init_node( int p );
void build_AC( int p );
void clear();
int query_word( char *s, int p, int id );
}AC;
void AC_automation::clear()
{
cur_id = 0;
root = 0;
init_node(root);
}
void AC_automation::init_node( int p )
{
for( int i = 0; i < WORD_SIZE; i ++ )
{
tree[p].next[i] = -1;
}
tree[p].count = 0;
tree[p].fail = -1;
}
void AC_automation::insert_word( char *str, int id )
{
int p = root, u;
while( *str )
{
u = *str - WORD_START;
if( tree[p].next[u] == -1 )
{
init_node(++cur_id);
tree[p].next[u] = cur_id;
}
p = tree[p].next[u];
str++;
}
tree[p].count = id;
}
void AC_automation::build_AC( int p )
{
int front = 0, rear = 0, t;
tree[p].fail = root;
q[ rear++] = p;
while( front != rear )
{
p = q[ front ++];
for( int i = 0; i < WORD_SIZE; i ++ )
if( tree[p].next[i] != -1 )
{
if( p == root ) tree[ tree[p].next[i] ].fail = root;
else
{
t = tree[p].fail;
while( t != root && tree[t].next[i] == -1 ) t = tree[t].fail;
if( tree[t].next[i] != -1 ) tree[ tree[p].next[i] ].fail = tree[t].next[i];
else tree[ tree[p].next[i] ].fail = root;
}
q[ rear ++ ] = tree[p].next[i];
}
}
}
int AC_automation::query_word( char *s, int p , int id)
{
int ans[20], top = 0;
for(int u, q; *s; s++ )
{
u = *s - WORD_START;
while( p != root && tree[p].next[u] == -1 ) p = tree[p].fail;
p = tree[p].next[u];
if( p == -1 ) p = root;
for( int q = p; q!=root && tree[q].count!=0 ; q = tree[q].fail )
ans[top++] = tree[q].count;
}
if( top )
{
sort(ans,ans+top);
printf("web %d: %d",id,ans[0]);
for( int i = 1; i < top; i ++ )
printf(" %d",ans[i]);
printf("\n");
return 1;
}
return 0;
}
char s[N];
int main()
{
char str[210];
for( int n; scanf("%d",&n)!=EOF; )
{
int total = 0;
AC.clear();
scanf("%d",&n);
for( int i = 1; i <= n; i ++ )
{
scanf("%s",str);
AC.insert_word(str,i);
}
AC.build_AC(AC.root);
scanf("%d",&n);
for( int i = 1; i <= n; i ++ )
{
scanf("%s",s);
total +=AC.query_word( s, AC.root, i);
}
printf("total: %d\n",total);
}
return 0;
}
// 动态
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#define N 100010
#define WORD_SIZE 129
using namespace std;
struct Node
{
Node *child[WORD_SIZE], *fail;
int is_word;
Node()
{
is_word = -1;
for( int i = 0; i < WORD_SIZE; i ++ )
child[i] = NULL;
fail = NULL;
}
}*q[N];
int ans[N], ans_n ;
char s[N];
void insert_word( Node *root, char *str, int d )
{
Node *p = root;
for( ; *str ; str ++ )
{
if( p->child[*str] == NULL ) p->child[*str] = new Node();
p = p->child[*str];
}
p->is_word = d;
}
void get_fail( Node *root )
{
Node *p;
q[0] = root;
for( int front = 0,rear = 1; front != rear; )
{
p = q[front++];
for( int i = 0; i < WORD_SIZE; i ++ )
{
if( p->child[i]!=NULL )
{
if( p == root ) p->child[i]->fail = root;
else
{
Node *t = p->fail;
while( t!=root && NULL == t->child[i] ) t = t->fail;
if( t->child[i] == NULL ) p->child[i]->fail = root;
else p->child[i]->fail = t->child[i];
}
q[rear++] = p->child[i];
}
}
}
}
int query( Node *root, char *s, int id )
{
int ans_n = 0, u;
for( Node *p = root ; *s; s++ )
{
while( p!= root && p->child[*s] == NULL ) p = p->fail;
p = p->child[*s];
if( p == NULL ) p = root;
for( Node *t = p; t!=root && t->is_word!=-1 ; t = t->fail )
ans[ ans_n++ ] = t->is_word;
}
if( ans_n >0 )
{
sort(ans,ans+ans_n);
printf("web %d: %d",id,ans[0]);
for( int i = 1; i < ans_n; i ++ )
printf(" %d",ans[i]);
printf("\n");
return 1;
}
return 0;
}
int main()
{
char str[410];
int total, n;
Node *root = new Node();
while( scanf("%d",&n)!=EOF )
{
root->is_word = -1;
for( int i = 0; i < WORD_SIZE; i ++ )
root->child[i] = NULL;
root->fail = NULL;
total = 0;
for( int i = 1; i<=n; i ++ )
{
scanf("%s",str);
insert_word(root,str,i);
}
get_fail(root);
scanf("%d",&n);
for( int i = 1; i <=n; i ++ )
{
scanf("%s",s);
total += query(root,s,i);
}
printf("total: %d\n",total);
}
return 0;
}