Given an N M matrix, your task is to nd the number of occurences of
an X Y pattern. Input The rst line contains a single integer t ( t
15), the number of test cases. For each case, the rst line contains
two integers N and M ( N;M 1000). The next N lines contain M
characters each. The next line contains two integers X and Y ( X;Y
100). The next X lines contain Y characters each. Output For each
case, output a single integer in its own line, the number of
occurrences.
把所有模板的行都插入AC自动机中,把原串的每一行在其中查找,找到以后在对应位置累加。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define M(a) memset(a,0,sizeof(a))
const int ss=26;
int son[10010][30],last[10010],fail[10010],n,m,x,y,tot,cnt[1010][1010],que[10010];
char a[1010][1010],b[110][110];
vector<int> val[10010];
void init()
{
int i;
scanf("%d%d",&n,&m);
for (i=1;i<=n;i++)
scanf("%s",a[i]+1);
scanf("%d%d",&x,&y);
for (i=1;i<=x;i++)
scanf("%s",b[i]+1);
M(son);
M(last);
M(fail);
M(cnt);
M(val);
tot=0;
}
void build()
{
int i,j,p,hd,tl,u;
for (i=1;i<=x;i++)
{
p=0;
for (j=1;j<=y;j++)
{
if (!son[p][b[i][j]-'a']) son[p][b[i][j]-'a']=++tot;
p=son[p][b[i][j]-'a'];
}
val[p].push_back(i);
}
hd=tl=1;
que[1]=0;
while (hd<=tl)
{
u=que[hd++];
if (val[fail[u]].size()) last[u]=fail[u];
else last[u]=last[fail[u]];
for (i=0;i<ss;i++)
if (son[u][i])
{
if (u) fail[son[u][i]]=son[fail[u]][i];
que[++tl]=son[u][i];
}
else son[u][i]=son[fail[u]][i];
}
}
void add(int i,int j,int p)
{
int k;
if (p)
{
for (k=0;k<val[p].size();k++)
if (i-val[p][k]+1>=1&&i-val[p][k]+1<=n&&j-y+1>=1&&j-y+1<=m)
cnt[i-val[p][k]+1][j-y+1]++;
add(i,j,last[p]);
}
}
void solve()
{
int i,j,k,p;
for (i=1;i<=n;i++)
{
p=0;
for (j=1;j<=m;j++)
{
p=son[p][a[i][j]-'a'];
if (val[p].size()) add(i,j,p);
else add(i,j,last[p]);
}
}
}
void out()
{
int i,j,ans=0;
for (i=1;i<=n;i++)
for (j=1;j<=m;j++)
if (cnt[i][j]==x) ans++;
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
init();
build();
solve();
out();
}
}