题意:
要检测一个字符串中,包含多少种模式串。但是主串和模式串都用base64表示,所以要先转过来。
题解:
转码后,建AC自动机,老题了不多说……但是因为是从base64转来的,所以取值为0~255,因为这个坑了很久。
//Time:230ms
//Memory:44824KB
//Length:3401B
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define MAXN 520
#define MAXM 44000
#define MAXL 5000
int to[MAXM][256],fail[MAXM],val[MAXM],tval[MAXM];
bool hav[MAXM],thav[MAXM];
struct _ACmachine
{
int top;
void init()
{
for(int i=0;i<top;++i) memset(to[i],0,sizeof(to[i]));
val[0]=0;
top=1;
fail[0]=0;
}
void addstr(int *s,int len)
{
int now=0;
for(int i=0;i<len;++i)
{
if(!to[now][s[i]])
{
to[now][s[i]]=top;
fail[top]=0;
val[top]=0;
hav[top]=0;
++top;
}
now=to[now][s[i]];
}
hav[now]=1;
val[now]=1;
}
void build()
{
queue<int> que;
for(int i=0;i<256;++i)
if(to[0][i])
que.push(to[0][i]);
while(que.size())
{
int h=que.front();
que.pop();
for(int i=0;i<256;++i)
{
int v=to[h][i];
if(v)
{
fail[v]=to[fail[h]][i];
hav[v]|=hav[fail[v]];
que.push(v);
}
else to[h][i]=to[fail[h]][i];
}
}
memcpy(tval,val,sizeof(val));
memcpy(thav,hav,sizeof(hav));
}
int check(int *s,int len)
{
int ans=0,now=0;
memcpy(val,tval,sizeof(val));
memcpy(hav,thav,sizeof(hav));
for(int i=0;i<len;++i)
{
now=to[now][s[i]];
if(hav[now])
{
int tmp=now;
while(hav[tmp])
ans+=val[tmp],val[tmp]=hav[tmp]=0,tmp=fail[tmp];
}
}
return ans;
}
}AC;
int n,m;
int tran[MAXL];
char st[MAXL];
bool midd[20000];
int trans()
{
int l=strlen(st),x,num=0,res=0;
if (l>2&&st[l-1]=='='&&st[l-2]=='=') l-=2;
else if (st[l-1]=='=') l-=1;
for (int i=0;i<l;i++)
{
if (st[i]>='A'&&st[i]<='Z') x=st[i]-'A';
else if (st[i]>='a'&&st[i]<='z') x=st[i]-'a'+26;
else if (st[i]>='0'&&st[i]<='9') x=st[i]-'0'+52;
else if (st[i]=='+') x=62;
else x=63;
for (int j=5;j>=0;j--)
midd[++num]=(x&(1<<j))>0;
}
num=num/8*8;
for (int i=1;i<=num;i+=8)
{
int t=0;
for (int j=i;j<=i+7;j++)
t=t*2+midd[j];
tran[res++]=t;
}
tran[res]=0;
return res;
}
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
AC.top=1;
while (scanf("%d",&n)!=-1)
{
int len;
AC.init();
for (int i=1;i<=n;i++)
{
scanf("%s",st);
len=trans();
// for(int i=0;;++i)
// {
// tran[i]=st[i];
// if(!st[i]) break;
// }
AC.addstr(tran,len);
}
AC.build();
scanf("%d",&m);
while (m--)
{
scanf("%s",st);
len=trans();
// for(int i=0;;++i)
// {
// tran[i]=st[i];
// if(!st[i]) break;
// }
int ans=AC.check(tran,len);
printf("%d\n",ans);
}
printf("\n");
}
return 0;
}