Code:
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<queue> using namespace std; const int maxn=103; const int maxd=1005; const int maxc=maxd*10; const int sigma=28; char A[maxd][maxd],B[maxn]; int ans[maxd][maxd]; int N,M,X,Y; # define pb push_back struct AC{ int ch[maxc][50],f[maxc]; vector<int>G[maxc]; queue<int>Q; int cnt=0; int idx(char t){return t-'a';} void init(){ memset(ch,0,sizeof(ch)); memset(f,0,sizeof(f)); memset(ans,0,sizeof(ans)); for(int i=0;i<maxc;++i)G[i].clear(); cnt=0; } void insert(char T[],int u){ int n=strlen(T); int j=0; for(int i=0;i<n;++i){ int a=idx(T[i]); if(!ch[j][a])ch[j][a]=++cnt; j=ch[j][a]; } G[j].pb(u); } void getfail(){ for(int i=0;i<=sigma;++i)if(ch[0][i]){Q.push(ch[0][i]);} while(!Q.empty()){ int r=Q.front();Q.pop(); for(int i=0;i<=sigma;++i){ int u=ch[r][i]; if(!u){ch[r][i]=ch[f[r]][i];continue;} Q.push(u); int v=f[r]; f[u]=ch[v][i]; } } } void operate() { for(int i=0;i<N;++i) { int p=0; for(int j=0;j<M;++j){ int c=idx(A[i][j]); p=ch[p][c]; int sz=G[p].size(); if(sz>0) { for(int g=0;g<sz;++g) { int h=G[p][g]; if(h<=i)ans[i-h][j-Y+1]+=1; } } } } } }op; int main(){ int T;scanf("%d",&T); while(T--){ op.init(); scanf("%d%d",&N,&M); for(int i=0;i<N;++i)scanf("%s",A[i]); scanf("%d%d",&X,&Y); for(int i=0;i<X;++i){scanf("%s",B);op.insert(B,i);} op.getfail(); op.operate(); int fin=0; for(int i=0;i<N;++i) for(int j=0;j<M;++j) if(ans[i][j]==X)++fin; printf("%d ",fin); } return 0; }