【bzoj2351】[BeiJing2011]Matrix hash表+双hash
2016-03-29 23:28
459 查看
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%的实际测试数据,M、N ≤ 1000,Q = 1000对于40%的数据,A = 1。
对于80%的数据,A ≤ 10。
对于100%的数据,A ≤ 100。
Source
写个hash表练习双hash是我闲的蛋疼
这个A不了bzoj2462,因为卡常了…模多了就是不好啊
所以那个题直接输出1就行了233
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long LL; const int SZ = 2010; const int SZ2 = 1000010; const int base1 = 13331; const int base2 = 1333331; const int mod1 = 1000003; const int mod2 = 998244353; char a[SZ][SZ]; struct pair{ int x,y; }h_sum[SZ][SZ],mi1[SZ],mi2[SZ],hh[SZ][SZ]; struct hashlist{ int x; int cnt; hashlist *nxt; }*h[SZ2],T[SZ2]; int Tcnt = 0; hashlist* newnode(int x) { hashlist *k = T + (Tcnt ++); k -> x = x; k -> cnt = 1; k -> nxt = NULL; return k; } void insert(int pos,int x) { pos = (pos % mod1 + mod1) % mod1; x = (x % mod2 + mod2) % mod2; if(!h[pos]) h[pos] = newnode(x); else for(hashlist *p = h[pos];p;p = p -> nxt) { if(p -> x == x) { p -> cnt ++; break; } if(!p -> nxt) { p -> nxt = newnode(x); break; } } } bool find(int x,int y) { x = (x % mod1 + mod1) % mod1; y = (y % mod2 + mod2) % mod2; for(hashlist *p = h[x];p;p = p -> nxt) if(p -> x == y) return true; return false; } char s[SZ][SZ]; int main() { int n,m,r,c; scanf("%d%d%d%d",&n,&m,&r,&c); for(int i = 1;i <= n;i ++) scanf("%s",a[i] + 1); mi1[0].x = mi1[0].y = 1; mi2[0].x = mi2[0].y = 1; for(int i = 1;i <= 1010;i ++) { mi1[i].x = (LL)mi1[i - 1].x * base1 % mod1; mi2[i].x = (LL)mi2[i - 1].x * base2 % mod1; mi1[i].y = (LL)mi1[i - 1].y * base1 % mod2; mi2[i].y = (LL)mi2[i - 1].y * base2 % mod2; } for(int i = 1;i <= n;i ++) for(int j = 1;j <= m;j ++) { h_sum[i][j].x = ((LL)h_sum[i][j - 1].x * base1 % mod1 + a[i][j] - '0' + 1) % mod1; h_sum[i][j].y = ((LL)h_sum[i][j - 1].y * base1 % mod2 + a[i][j] - '0' + 1) % mod2; } for(int i = 1;i <= n;i ++) for(int j = 1;j <= m;j ++) { h_sum[i][j].x = ((LL)h_sum[i - 1][j].x * base2 % mod1 + h_sum[i][j].x) % mod1; h_sum[i][j].y = ((LL)h_sum[i - 1][j].y * base2 % mod2 + h_sum[i][j].y) % mod2; } for(int i = 1;i <= n;i ++) for(int j = 1;j <= m;j ++) { int x = h_sum[i][j].x; x = (x - (LL)h_sum[i - r][j].x * mi2[r].x % mod1) % mod1; x = (x - (LL)h_sum[i][j - c].x * mi1[c].x % mod1) % mod1; x = (x + (LL)h_sum[i - r][j - c].x * mi1[c].x % mod1 * mi2[r].x % mod1) % mod1; int y = h_sum[i][j].y; y = (y - (LL)h_sum[i - r][j].y * mi2[r].y % mod2) % mod2; y = (y - (LL)h_sum[i][j - c].y * mi1[c].y % mod2) % mod2; y = (y + (LL)h_sum[i - r][j - c].y * mi1[c].y % mod2 * mi2[r].y % mod2) % mod2; insert(x,y); } int q; scanf("%d",&q); while(q --) { for(int i = 1;i <= r;i ++) scanf("%s",s[i] + 1); for(int i = 1;i <= r;i ++) for(int j = 1;j <= c;j ++) { hh[i][j].x = ((LL)hh[i][j - 1].x * base1 % mod1 + s[i][j] - '0' + 1) % mod1; hh[i][j].y = ((LL)hh[i][j - 1].y * base1 % mod2 + s[i][j] - '0' + 1) % mod2; } for(int i = 1;i <= r;i ++) for(int j = 1;j <= c;j ++) { hh[i][j].x = ((LL)hh[i - 1][j].x * base2 % mod1 + hh[i][j].x) % mod1; hh[i][j].y = ((LL)hh[i - 1][j].y * base2 % mod2 + hh[i][j].y) % mod2; } puts(find(hh[r][c].x,hh[r][c].y) ? "1" : "0"); } return 0; }
相关文章推荐
- 浪漫的表白 。刚接触编程语言 ,一个学长做的题。其实很简单,就是找规律输出,只是觉得输出特别浪漫,所以在此作为我人生第一个博客文章!!哈哈,大神之路 走起
- Python:使用Matplotlib绘图
- python 出现错误 SyntaxError: Non-ASCII character 的解决方法
- 数据库锁的种类
- progresql - 常用的管理命令
- listview中的radiobutton实现单选的两种方式而且可以控制另一控件button的是否可见
- 1-1-JS中的HTML属性操作
- MySQL性能分析
- 高水位线
- 并发学习笔记(二):synchronized代码块
- Java >>> 详解
- 基于进程的Quartz.NET管理系统QuartzService(一)
- 探究光栅图像学之水纹渲染与折射滤镜
- Python 2.7 学习笔记 元组的使用
- QWidget: Must construct a QApplication before a QWidget
- iOS 成员变量,实例变量,属性变量的区别,联系
- Scanner类的使用
- 结对项目 - 词频统计Ⅱ
- tcpdump命令安装
- static特别用法【静态导包】——Java包的静态导入