思路:裸的ac自动机,不过这题数据有点水,就算不用后缀链接也ac了
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2896
#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int n,m;
char s[205],t[10005];
vector<int> v;
struct Ac_automata
{
int val[maxn];
int ch[maxn][130];
int f[maxn],last[maxn];
int sz;
void init()
{
sz=1;
memset(val,0,sizeof(val));
memset(ch[0],0,sizeof(ch[0]));
}
int id(char c) {return c-0;}
void Insert(const char *s,int x)
{
int len=strlen(s);
int u=0;
for(int i=0;i<len;i++)
{
int c=id(s[i]);
if(!ch[u][c])
{
memset(ch[sz],0,sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
}
val[u]=x;
}
void getfail()
{
queue<int> q;
for(int c=0;c<130;c++)
{
int u=ch[0][c];
if(u) {f[u]=0;q.push(u);last[u]=0;}
}
while(!q.empty())
{
int r=q.front();
q.pop();
for(int c=0;c<130;c++)
{
int u=ch[r][c];
if(!u) continue;
q.push(u);
int j=f[r];
while(j&&!ch[j][c]) j=f[j];
f[u]=ch[j][c];
last[u]=val[f[u]]?f[u]:last[f[u]];
}
}
}
void get_ans(int j)
{
if(j)
{
v.push_back(val[j]);
get_ans(last[j]);
}
}
bool Find(const char *t)
{
bool flag=false;
int len=strlen(t);
int j=0;
for(int i=0;i<len;i++)
{
int c=id(t[i]);
while(j&&!ch[j][c]) j=f[j];
j=ch[j][c];
if(val[j])
{
flag=true;
v.push_back(val[j]);
get_ans(last[j]);
}
else if(last[j])
{
flag = true;
get_ans(last[j]);
}
}
return flag;
}
};
Ac_automata ac;
int main()
{
while(~scanf("%d",&n))
{
ac.init();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
ac.Insert(s,i);
}
ac.getfail();
scanf("%d",&m);
int ans=0;
for(int i=1;i<=m;i++)
{
v.clear();
scanf("%s",t);
bool flag=ac.Find(t);
if(flag)
{
ans++;
printf("web %d:",i);
sort(v.begin(),v.end());
for(int j=0;j<(int)v.size();j++)
{
printf(" %d",v[j]);
}
printf("\n");
}
}
printf("total: %d\n",ans);
}
return 0;
}