1. 程式人生 > >bzoj 2351 [BeiJing2011]Matrix——二維哈希

bzoj 2351 [BeiJing2011]Matrix——二維哈希

tdi matrix mes style define targe ref 二維 scan

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=2351

就是先把每行單獨從左到右掃著乘一個 b1 哈希起來,然後再按列從上往下乘一個 b2 哈希起來。

如果要取模的話,行的哈希和列的哈希應該模一樣的數。

當然不是讀入詢問再枚舉所有位置看哈希值啦……應該先把合法位置的哈希值用一個 map 之類的存一下存在性,詢問的時候直接查 map 就行了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include
<map> #define ull unsigned long long using namespace std; const int N=1005,b1=1e9+7,b2=993244853; int n,m,a,b; ull bn1[N],bn2[N],hs[N][N]; map<ull,bool> mp; int main() { scanf("%d%d%d%d",&n,&m,&a,&b); bn1[0]=1;for(int i=1;i<=n;i++)bn1[i]=bn1[i-1]*b1; bn2[0]=1
;for(int i=1;i<=m;i++)bn2[i]=bn2[i-1]*b2; for(int i=1,d;i<=n;i++) for(int j=1;j<=m;j++) { scanf("%1d",&d); d++;// hs[i][j]=hs[i][j-1]*b2+d; } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) hs[i][j]=hs[i-1][j]*b1+hs[i][j]; for(int i=a;i<=n;i++)
for(int j=(i==a?b:1);j<=m;j++) { ull tp=hs[i][j] - hs[i-a][j]*bn1[a] - hs[i][j-b]*bn2[b] + hs[i-a][j-b]*bn1[a]*bn2[b]; mp[tp]=1; } int Q; scanf("%d",&Q); while(Q--) { ull tmp=0; for(int i=1,d;i<=a;i++) for(int j=1;j<=b;j++) { scanf("%1d",&d); d++; tmp+=d*bn1[a-i]*bn2[b-j]; } puts(mp[tmp]?"1":"0"); } return 0; }

bzoj 2351 [BeiJing2011]Matrix——二維哈希