题解:二维矩阵hash,在大的矩阵上递推小矩阵的hash值可以从上到下逐次递推, s = s ∗ p [ B ] + g e t ( h [ j ] , l , r ) − g e t ( f [ j − A ] , l , r ) ∗ p [ A ∗ B ] s=s*p[B]+get(h[j],l,r)-get(f[j-A],l,r)*p[A*B] s=s∗p[B]+get(h[j],l,r)−get(f[j−A],l,r)∗p[A∗B],将hash值放入unordered_set中即可快速查找。
#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
const int N=1e3+5;
const int M=N*N;
const int base=131;
int n,m,a,b,q;
ull h[N][N],p[M];
char str[N][N];
ull get(ull f[],int l,int r){return f[r]-f[l-1]*p[r-l+1];}
int main()
{
scanf("%d%d%d%d",&n,&m,&a,&b);
p[0]=1;
for(int i=1;i<=n*m;i++)p[i]=p[i-1]*base;
for(int i=1;i<=n;i++){
scanf("%s",str[i]+1);
for(int j=1;j<=m;j++)h[i][j]=h[i][j-1]*base+str[i][j]-'0';
}
unordered_set<ull>ss;
for(int i=b;i<=m;i++){
ull s=0;
int l=i-b+1,r=i;
for(int j=1;j<=n;j++){
s=s*p[b]+get(h[j],l,r);
if(j>a)s=s-get(h[j-a],l,r)*p[a*b];
if(j>=a){
ss.insert(s);
}
}
}
scanf("%d",&q);
while(q--){
ull s=0;
for(int i=1;i<=a;i++){
scanf("%s",str[i]+1);
for(int j=1;j<=b;j++)s=s*base+str[i][j]-'0';
}
if(ss.count(s))puts("1");
else puts("0");
}
return 0;
}