参考博客:https://blog.csdn.net/bestsort/article/details/82947639
AC代码:hdu2222
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define LL long long
const int MOD=100000007;
const int inf=0x3f3f3f3f;
const LL inff=0x3f3f3f3f3f3f3f3f;
const LL N=15;
const LL M=15;
#define MEF(x) memset(x,-1,sizeof(x))
#define ME0(x) memset(x,0,sizeof(x))
#define MEI(x) memset(x,inf,sizeof(x))
struct Auto_c
{
int tire[500005][26],fail[500005],cnt[500005];
//tire 字典树
//fail 失配指针
//cnt 记录该单词出现次数,记录在单词最后一个字母对应的位置
int tot;
void init()
{
tot=0;
ME0(tire);
ME0(fail);
ME0(cnt);
}
void insertf(char *ss)
{
int p=0,len=strlen(ss);
for(int i=0;i<len;i++)
{
if(!tire[p][ss[i]-'a'])
{
tire[p][ss[i]-'a']=++tot;
}
p=tire[p][ss[i]-'a'];
}
cnt[p]++;
}
void getfail()
{
queue<int> q;
for(int i=0;i<26;i++)
{
if(tire[0][i])
{
fail[tire[0][i]]=0;
q.push(tire[0][i]);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<26;i++)
{
if(tire[x][i])
{
fail[tire[x][i]]=tire[fail[x]][i];
q.push(tire[x][i]);
}
else
{
tire[x][i]=tire[fail[x]][i];
}
}
}
}
int countf(char *ss)
{
int p=0,ans=0;
int len=strlen(ss);
for(int i=0;i<len;i++)
{
p=tire[p][ss[i]-'a'];
int temp=p;
while(temp&&cnt[temp]!=-1)
{
ans+=cnt[temp];
cnt[temp]=-1;//标记 防止重复计算
temp=fail[temp];
}
}
return ans;
}
}ac;
char str[55],s[1000005];
int main()
{
ios::sync_with_stdio(false);
int t;
cin>>t;
for(int t1=1;t1<=t;t1++)
{
int n;
cin>>n;
ac.init();
for(int i=1;i<=n;i++)
{
cin>>str;
ac.insertf(str);
}
ac.getfail();
cin>>s;
cout<<ac.countf(s)<<endl;
}
return 0;
}
AC代码:hdu2896
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<vector>
#include<cmath>
#include<stack>
#include<map>
#include<set>
using namespace std;
#define LL long long
const int MOD=100000007;
const int inf=0x3f3f3f3f;
const LL inff=0x3f3f3f3f3f3f3f3f;
const LL N=15;
const LL M=15;
#define MEF(x) memset(x,-1,sizeof(x))
#define ME0(x) memset(x,0,sizeof(x))
#define MEI(x) memset(x,inf,sizeof(x))
struct Node
{
string st;
int num;
};
int tire[100005][130],fail[100005],cnt[100005],sl[100005];
int tot;
void init()
{
tot=0;
// ME0(tire);
// ME0(fail);
// ME0(cnt);
//用memset会爆空间
}
void insertf(Node ss)
{
string s=ss.st;
int p=0,len=s.size();
for(int i=0;i<len;i++)
{
int x=s[i];
if(!tire[p][x])
{
tire[p][x]=++tot;
}
p=tire[p][x];
}
cnt[p]=ss.num;
}
void getfail()
{
queue<int> q;
for(int i=0;i<=128;i++)
{
if(tire[0][i])
{
fail[tire[0][i]]=0;
q.push(tire[0][i]);
}
}
while(!q.empty())
{
int x=q.front();
q.pop();
for(int i=0;i<=128;i++)
{
if(tire[x][i])
{
fail[tire[x][i]]=tire[fail[x]][i];
q.push(tire[x][i]);
}
else
{
tire[x][i]=tire[fail[x]][i];
}
}
}
}
int countf(Node ss)
{
int p=0,ans=0;
int lens=0;
string sa=ss.st;
int len=sa.size();
for(int i=0;i<len;i++)
{
int x=sa[i];
p=tire[p][x];
int temp=p;
while(temp)
{
ans+=cnt[temp];
if(cnt[temp]!=0)
{
sl[lens++]=cnt[temp];
}
temp=fail[temp];
}
}
if(ans!=0)
{
sort(sl,sl+lens);
cout<<"web "<<ss.num<<": ";
for(int i=0;i<lens;i++)
{
if(i==0)
{
cout<<sl[i];
}
else
{
cout<<' '<<sl[i];
}
}
cout<<endl;
}
return ans;
}
Node str;
int main()
{
ios::sync_with_stdio(false);
int n,m;
cin>>n;
init();
for(int i=1;i<=n;i++)
{
cin>>str.st;
str.num=i;
insertf(str);
}
getfail();
cin>>m;
int anss=0;
for(int i=1;i<=m;i++)
{
cin>>str.st;
str.num=i;
if(countf(str)!=0)
{
anss++;
}
}
cout<<"total: "<<anss<<endl;
return 0;
}