我没写hash,写了一些奇怪的做法,好像被hash随便操了……
如果没有多测,那么这道题是白书上的例题
把询问矩阵当作a个模板串,建成一个ac自动机
把一开始的矩阵当作n个串放到自动机上匹配,找到a个模板串所有出现的位置
然后找到对应矩阵的左上角上计数(即如果是第i个模板串出现在第x个串的第y个位置,则g[x-i+1,y-b+1]++)
然后判断是否有能接收a个模板串的左上角即可
加了一些剪枝过了2462……
然后2351无限TLE……
要来数据发现,当a=4 b=5的那个点跑了好长时间
有什么做法可以在a非常小的时候快速出解呢?(我就是不想写hash……)
由于询问的a,b都是一定的,我们可以把a行的矩阵压成一个串,每一列压成一个二进制位即可
这样就是给定n-a+1个长度为m的串,问一个长度为b的串是否是其中一个串的子串
这……后缀自动机随便做,这个点就跑得飞快了(因为这样复杂度是O(2^a*n*m+q*a*b了)
注意一下内存……
附上猥琐的代码
1 type node=record 2 po,next:longint; 3 end; 4 5 var trie,po:array[0..50010,'0'..'1'] of longint; 6 go:array[0..1500010,0..15] of longint; 7 w,f:array[0..1500010] of longint; 8 p,q:array[0..50010] of longint; 9 g,v:array[0..1010,0..1010] of longint; 10 e:array[0..1010] of node; 11 te,last,n,m,a,b,len,ans,i,j,t,tot,k,l:longint; 12 c:array[0..1010] of ansistring; 13 s:ansistring; 14 ch:char; 15 16 procedure add(x,y:longint); 17 begin 18 inc(len); 19 e[len].po:=y; 20 e[len].next:=p[x]; 21 p[x]:=len; 22 end; 23 24 procedure fill(x0,y0,x:longint); 25 var i,y,xx,yy:longint; 26 begin 27 i:=p[x]; 28 while i<>0 do 29 begin 30 y:=e[i].po; 31 xx:=x0-y+1; 32 yy:=y0-b+1; 33 if xx>0 then 34 begin 35 if v[xx,yy]<>te then 36 begin 37 v[xx,yy]:=te; 38 g[xx,yy]:=0; 39 end; 40 inc(g[xx,yy]); 41 if g[xx,yy]>ans then ans:=g[xx,yy]; 42 if ans=a then exit; 43 end; 44 i:=e[i].next; 45 end; 46 end; 47 48 procedure ac; 49 var j,h,r,x,y:longint; 50 c:char; 51 begin 52 h:=1; 53 r:=0; 54 for c:='0' to '1' do 55 if trie[0,c]>0 then 56 begin 57 inc(r); 58 q[r]:=trie[0,c]; 59 f[trie[0,c]]:=0; 60 end; 61 62 while h<=r do 63 begin 64 x:=q[h]; 65 for c:='0' to '1' do 66 if trie[x,c]>0 then 67 begin 68 y:=trie[x,c]; 69 inc(r); 70 q[r]:=y; 71 j:=f[x]; 72 while (j>0) and (trie[j,c]=0) do j:=f[j]; 73 f[y]:=trie[j,c]; 74 end; 75 inc(h); 76 end; 77 end; 78 79 procedure change(c:longint); 80 var q,p,np:longint; 81 begin 82 p:=go[last,c]; 83 if w[p]=w[last]+1 then last:=p 84 else begin 85 inc(t); np:=t; 86 w[np]:=w[last]+1; 87 go[np]:=go[p]; 88 f[np]:=f[p]; 89 f[p]:=np; 90 q:=last; 91 while go[q,c]=p do 92 begin 93 go[q,c]:=np; 94 q:=f[q]; 95 end; 96 last:=np; 97 end; 98 end; 99 100 procedure ins(c:longint); 101 var np,nq,p,q:longint; 102 begin 103 p:=last; 104 inc(t); last:=t; np:=t; 105 w[np]:=w[p]+1; 106 while (p<>0) and (go[p,c]=0) do 107 begin 108 go[p,c]:=np; 109 p:=f[p]; 110 end; 111 if p=0 then f[np]:=1 112 else begin 113 q:=go[p,c]; 114 if w[q]=w[p]+1 then f[np]:=q 115 else begin 116 inc(t); nq:=t; 117 w[nq]:=w[p]+1; 118 go[nq]:=go[q]; 119 f[nq]:=f[q]; 120 f[q]:=nq; f[np]:=nq; 121 while go[p,c]=q do 122 begin 123 go[p,c]:=nq; 124 p:=f[p]; 125 end; 126 end; 127 end; 128 end; 129 130 procedure make(l,r,m:longint); 131 var i,j:longint; 132 begin 133 for j:=1 to m do 134 begin 135 p[j]:=0; 136 for i:=l to r do 137 p[j]:=p[j]+g[i,j]*(1 shl (i-l)); 138 end; 139 end; 140 141 begin 142 readln(n,m,a,b); 143 if a>4 then 144 begin 145 for i:=1 to n do 146 readln(c[i]); 147 readln(te); 148 while te>0 do 149 begin 150 dec(te); 151 j:=0; 152 trie[0,'1']:=0; 153 trie[0,'0']:=0; 154 t:=0; 155 len:=0; 156 for i:=1 to a do 157 begin 158 readln(s); 159 j:=0; 160 for k:=1 to b do 161 begin 162 if trie[j,s[k]]=0 then 163 begin 164 inc(t); p[t]:=0; w[t]:=k; 165 trie[t,'0']:=0; trie[t,'1']:=0; 166 trie[j,s[k]]:=t; 167 end; 168 j:=trie[j,s[k]]; 169 end; 170 add(j,i); 171 end; 172 ac; 173 for i:=0 to t do 174 for ch:='0' to '1' do 175 begin 176 j:=i; 177 while (j>0) and (trie[j,ch]=0) do j:=f[j]; 178 j:=trie[j,ch]; 179 po[i,ch]:=j; 180 end; 181 182 ans:=0; 183 for i:=1 to n do 184 begin 185 j:=0; 186 for k:=1 to m do 187 begin 188 if not((c[i][k]>='0') and (c[i][k]<='1')) then break; 189 if b-w[j]>m-k+1 then break; 190 j:=po[j,c[i][k]]; 191 if p[j]<>0 then 192 begin 193 fill(i,k,j); 194 if ans=a then break; 195 end; 196 end; 197 if (ans=a) or (n-i+ans<a) then break; 198 end; 199 writeln(ans div a); 200 end; 201 end 202 else begin 203 t:=1; 204 for i:=1 to n do 205 begin 206 for j:=1 to m do 207 begin 208 read(ch); 209 g[i,j]:=ord(ch)-48; 210 end; 211 readln; 212 end; 213 for i:=1 to n-a+1 do 214 begin 215 make(i,i+a-1,m); 216 last:=1; 217 for j:=1 to m do 218 if go[last,p[j]]<>0 then change(p[j]) 219 else ins(p[j]); 220 end; 221 readln(te); 222 while te>0 do 223 begin 224 dec(te); 225 for i:=1 to a do 226 begin 227 for j:=1 to b do 228 begin 229 read(ch); 230 g[i,j]:=ord(ch)-48; 231 end; 232 readln; 233 end; 234 make(1,a,b); 235 j:=1; 236 ans:=1; 237 for i:=1 to b do 238 if go[j,p[i]]=0 then 239 begin 240 ans:=0; 241 break; 242 end 243 else j:=go[j,p[i]]; 244 writeln(ans); 245 end; 246 end; 247 end.