BZOJ.2462.[BeiJing2011]矩阵模板(二维Hash)
序列上的Hash和前缀和差不多,二维Hash也和二维前缀和差不多了。
预处理大矩阵所有r*c的小矩阵hash值,再对询问的矩阵Hash。
类比于序列上\(s[r]-s[l-1]*pow[r-l+1]\),比如\(s[i-r][j-c]\)多算了\(r*c\)次,乘个\(pow[r]*pow[c]\)就行。
用指针替掉数组的一维竟然慢点。。好吧毕竟也就一维,数据也不大。
//106864kb	1520ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 500000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define P 100000000
#define base1 12289
#define base2 786433
typedef unsigned int uint;//在这用unsigned long long好像没太大用吧...果然,光荣地T了
const int N=1005;
uint A[N][N],sum[N][N],pw1[N],pw2[N];
bool Hash[P];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-'0',c=gc());
	return now;
}
inline int read01()
{
	register char c=gc();
	for(;!isdigit(c);c=gc());
	return c-'0';
}
int main()
{
	int n=read(),m=read(),r=read(),c=read();
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=m; ++j) sum[i][j]=read01();
	pw1[0]=pw2[0]=1;
	for(int i=1; i<=n; ++i) pw1[i]=pw1[i-1]*base1;
	for(int i=1; i<=m; ++i) pw2[i]=pw2[i-1]*base2;
	for(int i=2; i<=n; ++i)//Row
		for(int j=1; j<=m; ++j) sum[i][j]+=sum[i-1][j]*base1;
	for(int i=1; i<=n; ++i)//Column
		for(int j=2; j<=m; ++j) sum[i][j]+=sum[i][j-1]*base2;
	for(int i=r; i<=n; ++i)
		for(int j=c; j<=m; ++j)
		{
			uint hash=sum[i][j]-sum[i-r][j]*pw1[r]-sum[i][j-c]*pw2[c]+sum[i-r][j-c]*pw1[r]
*pw2[c];
			Hash[hash%P]=1;
		}
	for(int Q=read(); Q--; )
	{
		for(int i=1; i<=r; ++i)
			for(int j=1; j<=c; ++j) A[i][j]=read01();
		for(int i=2; i<=r; ++i)
			for(int j=1; j<=c; ++j) A[i][j]+=A[i-1][j]*base1;
		for(int i=1; i<=r; ++i)
			for(int j=2; j<=c; ++j) A[i][j]+=A[i][j-1]*base2;
		puts(Hash[A[r][c]%P]?"1":"0");
	}
	return 0;
}
//106864kb	1544ms
#include <cstdio>
#include <cctype>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 500000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define P 100000000
#define base1 12289
#define base2 786433
typedef unsigned int uint;//在这用unsigned long long好像没太大用吧... 果然,光荣地T了
const int N=1005;
uint A[N][N],sum[N][N],pw1[N],pw2[N];
bool Hash[P];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
	int now=0;register char c=gc();
	for(;!isdigit(c);c=gc());
	for(;isdigit(c);now=now*10+c-'0',c=gc());
	return now;
}
inline int read01()
{
	register char c=gc();
	for(;!isdigit(c);c=gc());
	return c-'0';
}
int main()
{
	int n=read(),m=read(),r=read(),c=read();
	for(int i=1; i<=n; ++i)
		for(int j=1; j<=m; ++j) sum[i][j]=read01();
	pw1[0]=pw2[0]=1;
	for(int i=1; i<=n; ++i) pw1[i]=pw1[i-1]*base1;
	for(int i=1; i<=m; ++i) pw2[i]=pw2[i-1]*base2;
	for(int i=2; i<=n; ++i)//Row
	{
		uint *s=sum[i], *las=sum[i-1];
		for(int j=1; j<=m; ++j) s[j]+=las[j]*base1;
	}
	for(int i=1; i<=n; ++i)//Column
	{
		uint *s=sum[i];
		for(int j=2; j<=m; ++j) s[j]+=s[j-1]*base2;
	}
	for(int i=r; i<=n; ++i)
		for(int j=c; j<=m; ++j)
		{
			uint hash=sum[i][j]-sum[i-r][j]*pw1[r]-sum[i][j-c]*pw2[c]+sum[i-r][j-c]*pw1[r]*pw2[c];
			Hash[hash%P]=1;
		}
	for(int Q=read(); Q--; )
	{
		for(int i=1; i<=r; ++i)
			for(int j=1; j<=c; ++j) A[i][j]=read01();
		for(int i=2; i<=r; ++i)
		{
			uint *s=A[i], *las=A[i-1];
			for(int j=1; j<=c; ++j) s[j]+=las[j]*base1;
		}
		for(int i=1; i<=r; ++i)
		{
			uint *s=A[i];
			for(int j=2; j<=c; ++j) s[j]+=s[j-1]*base2;
		}
		puts(Hash[A[r][c]%P]?"1":"0");
	}
	return 0;
}
												
											BZOJ.2462.[BeiJing2011]矩阵模板(二维Hash)的更多相关文章
- BZOJ2462[Beijing2011]矩阵模板(二维Hash)
		
二维矩阵匹配问题,至今不知道Q的范围是多少,反正是要求做到读入复杂度. 二维Hash:就是一维的等效拓展,注意两维的Base不能相同. 其余就是一维Hash和二维前缀和的结合,可以自然溢出,据说概率很 ...
 - BZOJ 2462: [BeiJing2011]矩阵模板
		
2462: [BeiJing2011]矩阵模板 Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 915 Solved: 432[Submit][Stat ...
 - BZOJ 2462 [BeiJing2011]矩阵模板 矩阵哈希
		
昨天卡了一天常数...然后发现吧$unsigned\space long\space long$改成$unsigned$就可以过了$qwq$ 先把每一行的前缀哈希求出,然后再竖着把每个前缀哈希值哈希起 ...
 - BZOJ 2462 矩阵模板(二维hash)
		
题意:给出一个n*m的01矩阵,以及k个a*b的01矩阵,问每个是否能匹配原来的01矩阵. 由于k个矩阵的长和宽都是一样的,所以把原矩阵的所有a*b的子矩阵给hash出来.然后依次查找是否存在即可. ...
 - 牛客练习赛1 矩阵  字符串二维hash+二分
		
题目 https://ac.nowcoder.com/acm/contest/2?&headNav=www#question 解析 我们对矩阵进行二维hash,所以每个子矩阵都有一个额hash ...
 - 【BZOJ 2462】矩阵模板  (二维哈希)
		
题目 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在 原矩阵中出现过. 所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...
 - BZOJ 1567: [JSOI2008]Blue Mary的战役地图  矩阵二维hash
		
1567: [JSOI2008]Blue Mary的战役地图 Description Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提 ...
 - BZOJ2351[BeiJing2011]Matrix——二维hash
		
题目描述 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过.所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...
 - 【bzoj2351】[BeiJing2011]Matrix  二维Hash
		
题目描述 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过.所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...
 
随机推荐
- 引用EChart和Bootstrap
			
1.怎么引用Echart 下载之后,写一个html,里面这样写 <!DOCTYPE html> <html> <head> <meta charset=&qu ...
 - nodemon:让node自动重启
			
nodemon:服务器自动重启工具 当我们修改代码时,node必须要手动重启,但可以按照nodemon. npm install -g nodemon 安装完 nodemon 后,就可以用 nodem ...
 - bzoj千题计划287:bzoj1228: [SDOI2009]E&D
			
http://www.lydsy.com/JudgeOnline/problem.php?id=1228 打SG函数表,找规律: 若n是奇数m是奇数,则SG(n,m)=0 若n是偶数m是偶数,则SG( ...
 - NAT地址转换
			
2017年1月12日, 星期四 NAT地址转换 SNAT:源地址转换 DNAT:目标地址转换 null
 - [软件]在浏览器里添加MarkDown Here(插件)
			
1. 先来说说这个插件的作用是什么: 用于在网页一些编辑文本的地方, 使用MacDown编辑文本 支持大部分浏览器, https://github.com/adam-p/markdown-here ...
 - ASP.NET MVC学习(三)之过滤器Filter
			
http://www.cnblogs.com/yaopengfei/p/7910763.html
 - 浅谈 JSON 那些被转义的字符们
			
其实,之前我一直以为 JSON 会把 ASCII 可显示字符以外的统统转义为 Unicode,直到有一次我用 JSON.stringify 才发现,其实是 PHP 为我们想的太周到了. 我以前是一位 ...
 - 【LibreOJ】#6395. 「THUPC2018」城市地铁规划 / City   背包DP+Prufer序
			
[题目]#6395. 「THUPC2018」城市地铁规划 / City [题意]给定n个点要求构造一棵树,每个点的价值是一个关于点度的k次多项式,系数均为给定的\(a_0,...a_k\),求最大价值 ...
 - 20155237 2016-2017-2 《Java程序设计》第7周学习总结
			
20155237 2016-2017-2 <Java程序设计>第7周学习总结 教材学习内容总结 认识Lambda语法 Lambda 教材的引入循序渐近.深入浅出 Lambda去重复,回忆D ...
 - HDU 2159 FATE  (二维背包)
			
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159 解题报告:这题实际上是一个二维的背包问题,也可以由01背包扩展而来,01背包用一维数组,可想而知 ...