好像要用二维AC自动机的样子!?不对,还要优化不然还会MLE!?


naive。


哈希水过之。


中途某处忘强转导致调了良久。


2462丧心病狂卡stl常数,差点写平衡树了,然后想了想二分水之。


#include <cstdio>

#include <cstring>

#include <set>

#include <algorithm>


using namespace std;


typedef long long qw;

typedef unsigned long long uqw;


#define _l (qw)


const int rmod = 345379;

const int b1 = 3;

const int b2 = 3153131;

const int maxn = 1009;


int pb1[maxn];

int n, m, x, y, q, hr[maxn][maxn], t;

uqw hl[maxn][maxn], pb2[maxn];

char g[maxn];

uqw th[maxn * maxn];


void pre() {

pb1[0] = 1;

pb2[0] = 1;

for (int i = 1; i < maxn; ++ i) {

pb1[i] = _l pb1[i - 1] * b1 % rmod;

pb2[i] = pb2[i - 1] * b2;

}

}


bool findv(uqw x) {

int l = 0, r = t - 1;

while (l < r) {

int mid = (l + r) >> 1;

if (th[mid] == x)

return 1;

else if (x < th[mid])

r = mid;

else

l = mid + 1;

}

return th[l] == x;

}


int main() {

#ifndef ONLINE_JUDGE

freopen("in.txt", "r", stdin);

#endif


pre();

scanf("%d%d%d%d", &n, &m, &x, &y);

for (int i = 1; i <= n; ++ i) {

scanf("%s", g + 1);

hr[i][0] = 0;

for (int j = 1; j <= m; ++ j)

hr[i][j] = (_l hr[i][j - 1] * b1 + g[j] - 48) % rmod;

for (int j = m; j >= y; -- j)

hr[i][j] = (_l hr[i][j] - _l hr[i][j - y] * pb1[y] % rmod + rmod) % rmod;

}

t = 0;

for (int j = y; j <= m; ++ j) {

hl[0][j] = 0;

for (int i = 1; i <= n; ++ i)

hl[i][j] = hl[i - 1][j] * b2 + hr[i][j];

for (int i = n; i >= x; -- i) {

hl[i][j] = hl[i][j] - hl[i - x][j] * pb2[x];

th[t ++] = hl[i][j];

}

}

sort(th, th + t);

scanf("%d", &q);

while (q --) {

uqw hv = 0;

for (int i = 1; i <= x; ++ i) {

int hh = 0;

scanf("%s", g + 1);

for (int j = 1; j <= y; ++ j)

hh = (_l hh * b1 + g[j] - 48) % rmod;

hv =  hv * b2 + hh;

}

if (findv(hv))

puts("1");

else

puts("0");

}

}