【字符串二维hs】BZOJ 2462 BeiJing 2011 矩阵模板

2462: [BeiJing2011]矩阵模板

Time Limit: 2 Sec  Memory Limit: 128 MB
Submit: 1929  Solved: 820
[Submit][Status][Discuss]
Description

给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在
原矩阵中出现过。 
   所谓01矩阵,就是矩阵中所有元素不是0就是1。 
 

Input

输入文件的第一行为M、N、A、B,参见题目描述。 
接下来M行,每行N个字符,非0即1,描述原矩阵。 
接下来一行为你要处理的询问数Q。 
接下来Q个矩阵,一共Q*A行,每行B个字符,描述Q个01矩阵。 
 

Output

你需要输出Q行,每行为0或者1,表示这个矩阵是否出现过,0表示没有出现过,1表
示出现过。

Sample Input

3 3 2 2 

111 

000 

111 

3 

11 

00 

11 

11 

00 

11 
Sample Output

1 

0 

1 

 
HINT

对于100%的数据,N,M<=1000 A,B<=100

Source

Day4
T

二维hs就是横着一个seed,纵着一个seed,然后合并查询和矩阵前缀和没有区别,十分easy

注意n和m不要弄混了

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define N 1111
 5 #define p 13131
 6 #define q 1313131
 7 #define ull unsigned long long
 8 using namespace std;
 9 int n,m,a,b,qq;
10 ull hs[N][N],tt[N][N],sep[N],seq[N];
11 char in[N][N],ques[150][150];
12 inline ull geths(int l1,int l2,int r1,int r2)
13     {return hs[r2][l2]-hs[r2][l1-1]*seq[b]-hs[r1-1][l2]*sep[a]+hs[r1-1][l1-1]*sep[a]*seq[b];}
14 int main()
15 {
16     scanf("%d%d%d%d",&n,&m,&a,&b);
17     sep[0]=seq[0]=1;
18     for(int i=1;i<N;i++)sep[i]=sep[i-1]*p,seq[i]=seq[i-1]*q;
19     for(int i=1;i<=m;i++)
20         scanf("%s",in[i]+1);
21     for(int i=1;i<=m;i++)
22         for(int j=1;j<=n;j++)
23             hs[i][j]=hs[i-1][j]*p+hs[i][j-1]*q-hs[i-1][j-1]*p*q+in[i][j];
24     scanf("%d",&qq);
25     for(int que=1;que<=qq;que++)
26     {
27         for(int i=1;i<=a;i++)
28             scanf("%s",ques[i]+1);
29         memset(tt,0,sizeof(tt));
30         for(int i=1;i<=a;i++)
31             for(int j=1;j<=b;j++)
32                 tt[i][j]=tt[i-1][j]*p+tt[i][j-1]*q-tt[i-1][j-1]*p*q+ques[i][j];
33         ull val=tt[a][b];
34         bool fl=0;
35         for(int l1=1;l1+b-1<=n;l1++)
36         {
37             int l2=l1+b-1;
38             for(int r1=1;r1+a-1<=m;r1++)
39             {
40                 int r2=r1+a-1;
41                 if(geths(l1,l2,r1,r2)==val)
42                     {fl=1;break;}
43             }
44             if(fl)break;
45         }
46         if(fl)printf("1\n");
47         else printf("0\n");
48     }
49     return 0;
50 }

 

posted @ 2019-01-01 11:11  浅夜_MISAKI  阅读(143)  评论(0编辑  收藏  举报