链接
题解
二维字符串
h
a
s
h
hash
hash,对行和列分别选取一个
b
a
s
e
base
base进行字符串
h
a
s
h
hash
hash,注意两个
b
a
s
e
base
base不能相同,否则
A
A
A与
A
T
A^T
AT的
h
a
s
h
hash
hash值就相等了,通过容斥
O
(
1
)
O(1)
O(1)得到子矩阵的
h
a
s
h
hash
hash值。
这里直接用
u
n
s
i
g
n
e
d
unsigned
unsigned
l
o
n
g
long
long
l
o
n
g
long
long避开取模。
代码
#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 1; i <= (n); i++)
#define sqr(x) ((x) * (x))
const int maxn = 1000 + 10;
const int maxm = 1000000 + 50;
const int maxt = 500 + 5;
typedef long long LL;
typedef unsigned long long uLL;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
const LL unit = 1LL;
const int INF = 0x3f3f3f3f;
const LL Inf = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-8;
const double inf = 1e15;
const double pi = acos(-1.0);
const LL mod = 1000000007;
const uLL rp = 131;
const uLL cp = 13331;
int n, m, a, b;
uLL gra[maxn][maxn];
uLL sum[maxn][maxn];
uLL Rpow[maxn], Cpow[maxn];
set<uLL> uset;
inline uLL get_hash(int i, int j, int x, int y, uLL sum[][maxn])
{
uLL h = sum[x][y];
h -= sum[i - 1][y] * Rpow[a];
h -= sum[x][j - 1] * Cpow[b];
h += sum[i - 1][j - 1] * Rpow[a] * Cpow[b];
return h;
}
int main()
{
// ios::sync_with_stdio(false);
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
cin >> n >> m >> a >> b;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
scanf("%1llu", &sum[i][j]);
Rpow[0] = Cpow[0] = 1;
for (int i = 1; i <= m; i++)
Cpow[i] = Cpow[i - 1] * cp;
for (int i = 1; i <= n; i++)
Rpow[i] = Rpow[i - 1] * rp;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
sum[i][j] += sum[i][j - 1] * cp;
for (int j = 1; j <= m; j++)
for (int i = 1; i <= n; i++)
sum[i][j] += sum[i - 1][j] * rp;
for (int i = 1; i + a - 1 <= n; i++)
for (int j = 1; j + b - 1 <= m; j++)
{
int x = i + a - 1, y = j + b - 1;
uset.insert(get_hash(i, j, x, y, sum));
}
int q;
scanf("%d", &q);
while (q--)
{
for (int i = 1; i <= a; i++)
for (int j = 1; j <= b; j++)
scanf("%1llu", &gra[i][j]);
for (int i = 1; i <= a; i++)
for (int j = 1; j <= b; j++)
gra[i][j] += gra[i][j - 1] * cp;
for (int j = 1; j <= b; j++)
for (int i = 1; i <= a; i++)
gra[i][j] += gra[i - 1][j] * rp;
if (uset.count(get_hash(1, 1, a, b, gra)))
printf("1\n");
else
printf("0\n");
}
return 0;
}