Matrix Matcher UVA - 11019 (哈希)

Matrix Matcher

 UVA - 11019 

题意:给两个二维字符串,问小的在大的里面出现了多少次。

本来看到白书上说ac自动机,搜题解看到有个人用hash写的,就学习了下。。。orz

等下再去敲自动机。。。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define ull unsigned long long
 4 #define CLR(m,a) memset(m,a,sizeof(m))
 5 const int maxn=1010;
 6 ull base,seed=131,tpx[maxn][maxn],tpy[maxn][maxn],ans[maxn*maxn];
 7 int n,m;
 8 
 9 char p[maxn][maxn],q[maxn][maxn];
10 int Lfind(ull qsum)
11 {
12     int L=0,R=n*m-1;
13     int res=-1;
14     while(L<=R){
15         int mid=L+(R-L)/2;
16         if(ans[mid]>=qsum){
17             if(ans[mid]==qsum) res=mid;
18             R=mid-1;
19         }
20         else L=mid+1;
21     }
22     return res;
23 }
24 int Rfind(ull qsum)
25 {
26     int L=0,R=n*m-1;
27     int res=-1;
28     while(L<=R){
29         int mid=L+(R-L)/2;
30         if(ans[mid]<=qsum){
31             if(ans[mid]==qsum) res=mid;
32             L=mid+1;
33         }
34         else R=mid-1;
35     }
36     return res;
37 }
38 int main()
39 {
40     int t;
41     scanf("%d",&t);
42     while(t--){
43         scanf("%d%d",&n,&m);
44         for(int i=0;i<n;i++)
45             scanf("%s",p[i]);
46         int x,y;
47         scanf("%d%d",&x,&y);
48         for(int i=0;i<x;i++)
49             scanf("%s",q[i]);
50         if(x>n||y>m){
51             puts("0");
52             continue;
53         }
54         CLR(tpx,0);
55         base=1;
56         for(int i=1;i<y;i++) base*=seed;
57         for(int i=0;i<n;i++){
58             for(int j=0;j<y;j++) tpx[i][y-1]=tpx[i][y-1]*seed+p[i][j];
59             for(int j=y;j<m;j++) tpx[i][j]=(tpx[i][j-1]-p[i][j-y]*base)*seed+p[i][j];
60         }
61         CLR(tpy,0);
62         base=1;
63         for(int i=1;i<x;i++) base*=seed;
64         for(int i=0;i<m;i++){
65             for(int j=0;j<x;j++) tpy[x-1][i]=tpy[x-1][i]*seed+tpx[j][i];
66             for(int j=x;j<n;j++) tpy[j][i]=(tpy[j-1][i]-tpx[j-x][i]*base)*seed+tpx[j][i];
67         }
68         int id=0;
69         for(int i=0;i<n;i++)
70             for(int j=0;j<m;j++)
71             ans[id++]=tpy[i][j];
72         sort(ans,ans+id);
73         //求模板矩阵的哈希值
74         ull qsum=0;
75         for(int i=0;i<x;i++){
76             ull temp=0;
77             for(int j=0;j<y;j++) temp=temp*seed+q[i][j];
78             qsum=qsum*seed+temp;
79         }
80         if(Lfind(qsum)==-1){
81             puts("0");
82             continue;
83         }
84         printf("%d\n",Rfind(qsum)-Lfind(qsum)+1);
85     }
86     return 0;
87 }
View Code

 

posted @ 2017-08-18 10:34  yijiull  阅读(193)  评论(0编辑  收藏  举报