题目描述

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

输入

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

输出

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

样例输入

3 3 2 2
111
000
111
3
11
00
11
11
00
11

样例输出

1
0
1


题解

二维Hash

因为一维Hash就是一维前缀和,所以二维Hash就是二维前缀和——GXZlegend

事实上的确是这样的,维护矩阵 $(1...n,1...m)$ 的Hash值的方法与二维前缀和类似,利用容斥关系推出。其中,设行列两个base,然后乘上base相加减即可。

由于每次询问的 $a$ 和 $b$ 相同,因此预处理出所有原矩阵的 $a × b$ 的子矩阵的Hash值,存到哈希表中,查询时直接找是否有相等的Hash值即可。

注意:行列base不能相同(不然沿主对角线反转Hash值不变);01串的Hash不能以0和1作为取值,应以'0'和'1'作为取值。

具体看代码吧。

时间复杂度 $O(nm+qab)$

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 1010
#define M 12345678
using namespace std;
typedef unsigned long long ull;
struct data
{
int head[M] , next[N * N] , tot;
ull v[N * N];
inline void insert(ull x)
{
if(!head[x % M]) head[x % M] = ++tot , v[tot] = x;
else
{
int i;
for(i = head[x % M] ; next[i] ; i = next[i])
if(v[i] == x)
return;
next[i] = ++tot , v[tot] = x;
}
}
inline int count(ull x)
{
int i;
for(i = head[x % M] ; i ; i = next[i])
if(v[i] == x)
return 1;
return 0;
}
}mp;
ull v[N][N] , w[N][N];
char str[N];
int main()
{
int n , m , a , b , q , i , j;
ull c = 1 , d = 1;
scanf("%d%d%d%d" , &n , &m , &a , &b);
for(i = 1 ; i <= n ; i ++ )
{
scanf("%s" , str + 1);
for(j = 1 ; j <= m ; j ++ )
v[i][j] = str[j] + v[i][j - 1] * 233 + v[i - 1][j] * 2333 - v[i - 1][j - 1] * 233 * 2333;
}
for(i = 1 ; i <= b ; i ++ ) c *= 233;
for(i = 1 ; i <= a ; i ++ ) d *= 2333;
for(i = a ; i <= n ; i ++ )
for(j = b ; j <= m ; j ++ )
mp.insert(v[i][j] - v[i][j - b] * c - v[i - a][j] * d + v[i - a][j - b] * c * d);
scanf("%d" , &q);
while(q -- )
{
for(i = 1 ; i <= a ; i ++ )
{
scanf("%s" , str + 1);
for(j = 1 ; j <= b ; j ++ )
w[i][j] = str[j] + w[i][j - 1] * 233 + w[i - 1][j] * 2333 - w[i - 1][j - 1] * 233 * 2333;
}
printf("%d\n" , mp.count(w[a][b]));
}
return 0;
}

【bzoj2351】[BeiJing2011]Matrix 二维Hash的更多相关文章

  1. BZOJ2351[BeiJing2011]Matrix——二维hash

    题目描述 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过.所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...

  2. bzoj 2351 [BeiJing2011]Matrix——二维哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2351 就是先把每行单独从左到右扫着乘一个 b1 哈希起来,然后再按列从上往下乘一个 b2 哈 ...

  3. BZOJ.2462.[BeiJing2011]矩阵模板(二维Hash)

    题目链接 序列上的Hash和前缀和差不多,二维Hash也和二维前缀和差不多了. 预处理大矩阵所有r*c的小矩阵hash值,再对询问的矩阵Hash. 类比于序列上\(s[r]-s[l-1]*pow[r- ...

  4. UVA 11019 Matrix Matcher(二维hash + 尺取)题解

    题意:在n*m方格中找有几个x*y矩阵. 思路:二维hash,总体思路和一维差不太多,先把每行hash,变成一维的数组,再对这个一维数组hash变成二维hash.之前还在想怎么快速把一个矩阵的hash ...

  5. BZOJ2462[Beijing2011]矩阵模板(二维Hash)

    二维矩阵匹配问题,至今不知道Q的范围是多少,反正是要求做到读入复杂度. 二维Hash:就是一维的等效拓展,注意两维的Base不能相同. 其余就是一维Hash和二维前缀和的结合,可以自然溢出,据说概率很 ...

  6. UVA 11019 Matrix Matcher ( 二维字符串匹配, AC自动机 || 二维Hash )

    题目: 传送门 题意: 给你一个 n * m 的文本串 T, 再给你一个 r * c 的模式串 S: 问模式串 S 在文本串 T 中出现了多少次. 解: 法一: AC自动机 (正解) 670ms 把模 ...

  7. BZOJ 1567 Blue Mary的战役地图(二维hash+二分)

    题意: 求两个矩形最大公共子正方形.(n<=50) 范围这么小可以枚举子正方形的边长.那么可以对这个矩形进行二维hash,就可以在O(1)的时候求出任意子矩形的hash值.然后判断这些正方形的h ...

  8. 二维hash

    题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行两个整数n, m代表矩阵的长和宽: 接下来n行,每 ...

  9. 牛客练习赛1 矩阵 字符串二维hash+二分

    题目 https://ac.nowcoder.com/acm/contest/2?&headNav=www#question 解析 我们对矩阵进行二维hash,所以每个子矩阵都有一个额hash ...

随机推荐

  1. StringUtils工具类用法

    /*1.字符串以prefix开始*/ StringUtils.startsWith("sssdf","");//结果是:true StringUtils.sta ...

  2. 使用Nexus搭建Maven私服问题总结

    #业务场景 最近项目要交付给客户了,之前项目开发和测试一直都是使用公司内部的一套环境,项目交付后客户购置了大量服务器,也要将整套测试环境迁移至客户的服务器上,后续的需求变更以及新需求的开发都会在客户服 ...

  3. RDS for MySQL有哪些限制

    原文来自:https://help.aliyun.com/knowledge_detail/41834.html 1.不支持在命令行创建数据库和数据库账号.只支持在RDS管理控制台操作. 2.不支持M ...

  4. 一个web应用的诞生(4)--数据存储

    上一章实现了登录的部分功能,之所以说是部分功能,是因为用户名和密码写成固定值肯定是不可以的,一个整体的功能,至少需要注册,登录,密码修改等,这就需要提供一个把这些值存储到数据库的能力. 当前的主流数据 ...

  5. Jmeter资源监控工具ServerAgent运行原理的一些研究

    用过Jmeter的应该都了解,有个ServerAgent工具,放在linux或者windows服务器上开启服务后,在Jmeter中配置下监视器,就可以抓取到服务器的一些资源信息,抓取的主要是cpu.内 ...

  6. 数据库sql优化总结之2-百万级数据库优化方案+案例分析

    项目背景 有三张百万级数据表 知识点表(ex_subject_point)9,316条数据 试题表(ex_question_junior)2,159,519条数据 有45个字段 知识点试题关系表(ex ...

  7. MATLAB 笔记

    MATLAB的学习 Matlab 主要有5大部分构成,分别是MATLAB语言,桌面工具与开发环境,数学函数库 ,图形系统和应用程序接口.以及众多的专业工具.

  8. sql server block如何查询并kill

    本帖提供两种做法,可避免在 SQL Server 事务锁定时产生的不正常或长时间阻塞,让用户和程序也无限期等待,甚至引起 connection pooling 连接数超过容量. 所谓的「阻塞」,是指当 ...

  9. 使用 Sublime Text 做 Javascript 编辑器 - 集成 JSHint 问题检测工具

    JSHint(jshint.com)是 Javascritp 代码质量工具,可以帮助开发人员发现 Javascript 代码中的错误和潜在的问题.jshint.com 是一个在线编辑器,我们可以为 S ...

  10. Centos7 Ntp 时间服务器

    Centos7 Ntp 时间服务器 安装环境 [root@m02 ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) 安装 ...