不会AC自动机,就来份邪教的矩阵hash;存个模板留作纪念!
AC自动机的做法在大白书上有作为例题来讲的!
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
#define ull unsigned long long
#define ll long long
#define seed1 131
#define seed2 1313
#define mod 0x7FFFFFFF
char s[1010][1010],p[110][110];
ull h[1010][1010],hh[1010][1010];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,sn,sm;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",s[i]);
scanf("%d%d",&sn,&sm);
for(int i=0;i<sn;i++)
scanf("%s",p[i]);
ull ha=0;
for(int i=0;i<sn;i++)
{
ull hb=0;
for(int j=0;j<sm;j++)
hb=hb*seed1+p[i][j];
ha=ha*seed2+hb;
}
//ha=ha&mod;
//printf("p==%lld\n",ha);
ull base=1;
for(int i=0;i<sm;i++)
base*=seed1;
for(int i=0;i<n;i++)
{
ull hi=0;
for(int j=0;j<sm;j++){
hi=hi*seed1+s[i][j];
}
h[i][sm-1]=hi;
for(int j=sm;j<m;j++)
h[i][j]=h[i][j-1]*seed1-s[i][j-sm]*base+s[i][j];
}
/*for(int i=0;i<n;i++)
{
for(int j=sm-1;j<m;j++)
printf("%lld ",h[i][j]);
printf("\n");
}*/
int ans=0;
base=1;
for(int i=0;i<sn;i++)
base*=seed2;
for(int i=sm-1;i<m;i++)
{
ull hi=0;
for(int j=0;j<sn;j++){
hi=hi*seed2+h[j][i];
}
hh[sn-1][i]=hi;
if(hi==ha) ans++;
for(int j=sn;j<n;j++){
hh[j][i]=hh[j-1][i]*seed2-h[j-sn][i]*base+h[j][i];
if(hh[j][i]==ha) ans++;
}
}
printf("%d\n",ans);
}
return 0;
}