首先,这篇博客,是用来搞笑的。
看了一眼题目,内心:好像是后缀自动机啊,可是不会写sad...看起来大家运行时间不是很长啊暴力吧!然后写了一个又长又慢的弱智暴力,意料之中的TLE了。
要是发现代码的问题,或者有比较好的暴力idea,欢迎交流!
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<set>
#define N 11000
#define M 100010
#define X 60010
using namespace std;
typedef long long LL;
set<LL>Q1,Q2;
int n,qq,len[N],st[N],mlen,len2[X],num[X],ans[X];
char s[M],c[M];
LL mod[2]={1000000007,1000000009},d[M][2],ci[M][2],bas=127,hah[X][2];
LL hsh(int l,int r,int k,bool x)
{
LL k1=d[l-1][k];
if(x)k1=0;
return (d[r][k]-k1*ci[r-l+1][k]%mod[k]+mod[k])%mod[k];
}
bool cmp(int a,int b)
{
return len2[a]<len2[b];
}
void hhh(int th,int fr,int to)
{
if(th>mlen)return ;
for(int i=1;i<=n;i++)
if(len[i]>=th)
{
Q1.clear(),Q2.clear();
for(int j=0;j<len[i];j++)
{
if(len[i]-j<th)break;
LL a1=hsh(st[i]+j,st[i]+j+th-1,0,(j==0)),a2=hsh(st[i]+j,st[i]+j+th-1,1,(j==0));
Q1.insert(a1),Q2.insert(a2);
}
for(int k=fr;k<=to;k++)
{
int p=num[k];
if(Q1.count(hah[p][0])&&Q2.count(hah[p][1]))ans[p]++;
}
}
}
int main()
{
scanf("%d%d",&n,&qq);
st[0]=1;
for(int i=1;i<=n;i++)
{
scanf("%s",c);
len[i]=strlen(c);
if(len[i]>mlen)mlen=len[i];
st[i]=st[i-1]+len[i-1];
for(int j=0;j<len[i];j++)s[j+st[i]]=c[j];
}
ci[0][0]=ci[0][1]=1;
for(int i=1;i<=mlen;i++)ci[i][0]=ci[i-1][0]*bas%mod[0],ci[i][1]=ci[i-1][1]*bas%mod[1];
for(int i=1;i<=n;i++)
{
d[st[i]][0]=bas+s[st[i]];
d[st[i]][1]=bas+s[st[i]];
for(int j=1;j<len[i];j++)
{
d[j+st[i]][0]=(d[j+st[i]-1][0]*bas+s[j+st[i]])%mod[0];
d[j+st[i]][1]=(d[j+st[i]-1][1]*bas+s[j+st[i]])%mod[1];
}
}
for(int i=1;i<=qq;i++)
{
scanf("%s",c);
LL t1=0,t2=0;
len2[i]=strlen(c);
for(int j=0;j<len2[i];j++)
{
t1=(t1*bas+c[j])%mod[0];
t2=(t2*bas+c[j])%mod[1];
}
hah[i][0]=t1,hah[i][1]=t2;
}
for(int i=1;i<=qq;i++)num[i]=i;
sort(num+1,num+qq+1,cmp);
for(int i=1;i<=qq;i++)
{
int j=i;
while(j<n&len2[num[j+1]]==len2[num[i]])j++;
hhh(len2[num[i]],i,j);
}
for(int i=1;i<=qq;i++)printf("%d\n",ans[i]);
return 0;
}