Link:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3430
#include <bits/stdc++.h>
using namespace std;
/*
题意:给出n个编码后的模板串,然后有M次询问,每次询问输入一个编码后的文本串,
问在编码前,有多少个模板串在文本串中出现过。
*/
const int N = 55000;
const int M = 256;
int num[N],code[N];
int digit[N];
int change(char ch)
{
if(ch<='Z'&&ch>='A')
return ch-'A';
else if(ch<='z'&&ch>='a')
return 26+ch-'a';
else if(ch<='9'&&ch>='0')
return 52+ch-'0';
else if(ch=='+')
return 62;
return 63;
}
int slen;
void translate(char *str)
{
int l=strlen(str);
while(str[l-1]=='=')
l--;
for(int i=0; i<l; i++)
num[i]=change(str[i]);
memset(code,0,sizeof(code));
memset(digit,0,sizeof(digit));
slen=0;
for(int i=0; i<l; i++)
{
for(int j=1; j<=6; j++)
{
if(num[i]&1)
digit[(i+1)*6-j]=1;
else digit[(i+1)*6-j]=0;
num[i]>>=1;
}
}
for(int i=0; i<l*6/8; i++)
{
for(int j=0; j<8; j++)
{
code[i]<<=1;
code[i]+=digit[i*8+j];
}
}
slen=l*6/8;
// for(int i = 0; i < slen; i++){
// printf("%d ",code[i]);
// }
// puts("");
}
int n;
struct Aho
{
struct Node
{
int nex[M];
int fail,endd;
} node[N];
int Size;
queue<int> que;
int newnode()
{
memset(node[Size].nex,0,sizeof(node[Size].nex));
node[Size].fail = node[Size].endd = 0;
return Size++;
}
void init()
{
while(!que.empty()) que.pop();
Size = 0;
newnode();
}
void Insert(int f)
{
int len = slen;
int now = 0; //当前所在的点
for(int i = 0; i < len; i++)
{
int t = code[i];
if(node[now].nex[t]==0)
node[now].nex[t] = newnode();
now = node[now].nex[t];
}
node[now].endd = f;
}
void build()
{
node[0].fail = 0;
for(int i = 0; i < M; i++)
{
if(node[0].nex[i])
{
node[node[0].nex[i]].fail = 0;
que.push(node[0].nex[i]);
}
}
while(!que.empty())
{
int u = que.front();
que.pop();
for(int i = 0; i < M; i++)
{
if(node[u].nex[i]==0)
node[u].nex[i] = node[node[u].fail].nex[i];
else
{
node[node[u].nex[i]].fail = node[node[u].fail].nex[i];
que.push(node[u].nex[i]);
}
}
}
}
int vis[N];
int match()
{
memset(vis,0,sizeof(vis));
int len = slen;
int res = 0, now = 0;
for(int i = 0; i < len; i++)
{
int t = code[i];
now = node[now].nex[t];
int temp = now;
while(temp)
{
if(node[temp].endd)
vis[node[temp].endd] = 1;
temp = node[temp].fail;
}
}
for(int i = 1; i <= n; i++)
{
if(vis[i])
res++;
}
return res;
}
} aho;
char str[N];
int main()
{
while(scanf("%d",&n)!=EOF)
{
aho.init();
for(int i=0; i<n; i++)
{
scanf("%s",str);
translate(str);
aho.Insert(1+i);
}
aho.build();
int m;
scanf("%d",&m);
for(int i=0; i<m; i++)
{
scanf("%s",str);
translate(str);
printf("%d\n",aho.match());
}
puts("");
}
return 0;
}