[luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)
传送门
很蒙蔽,不知道怎么搞。
网上看题解有说可以哈希+二分搞,也有的人说用Manacher搞,Manacher是什么鬼?以后再学。
对于这个题,可以从矩阵4个角hash一遍,然后枚举矩阵中的点,再二分半径。
但是得考虑边的长度为奇偶所带来的影响。
比如
1 1
1 1
这个边数为偶数的矩阵显然没法搞。
所以得在矩阵中插入0,
变成
0 0 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 0 1 0
0 0 0 0 0
具体操作就看代码好了。
然后只枚举 行 + 列 为偶数的点就行。
注意 用 unsigned long long 会超时和超空间,数据允许用 unsigned int
——代码
1 #include <cstdio> 2 #include <iostream> 3 #define UI unsigned int 4 5 const int MAXN = 2010, bs1 = 19260817, bs2 = 20011001; 6 int n, m, ans; 7 UI sum[4][MAXN][MAXN], base1[MAXN], base2[MAXN]; 8 9 inline int read() 10 { 11 int x = 0, f = 1; 12 char ch = getchar(); 13 for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1; 14 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0'; 15 return x * f; 16 } 17 18 inline int min(int x, int y) 19 { 20 return x < y ? x : y; 21 } 22 23 inline bool pd(int x, int y, int l) 24 { 25 UI t, h; 26 h = sum[0][x + l - 1][y + l - 1] 27 - sum[0][x - l][y + l - 1] * base1[l + l - 1] 28 - sum[0][x + l - 1][y - l] * base2[l + l - 1] 29 + sum[0][x - l][y - l] * base1[l + l - 1] * base2[l + l - 1]; 30 t = sum[1][x + l - 1][y - l + 1] 31 - sum[1][x - l][y - l + 1] * base1[l + l - 1] 32 - sum[1][x + l - 1][y + l] * base2[l + l - 1] 33 + sum[1][x - l][y + l] * base1[l + l - 1] * base2[l + l - 1]; 34 if(h ^ t) return 0; 35 t = sum[2][x - l + 1][y + l - 1] 36 - sum[2][x + l][y + l - 1] * base1[l + l - 1] 37 - sum[2][x - l + 1][y - l] * base2[l + l - 1] 38 + sum[2][x + l][y - l] * base1[l + l - 1] * base2[l + l - 1]; 39 if(h ^ t) return 0; 40 t = sum[3][x - l + 1][y - l + 1] 41 - sum[3][x + l][y - l + 1] * base1[l + l - 1] 42 - sum[3][x - l + 1][y + l] * base2[l + l - 1] 43 + sum[3][x + l][y + l] * base1[l + l - 1] * base2[l + l - 1]; 44 if(h ^ t) return 0; 45 return 1; 46 } 47 48 inline int work(int i, int j) 49 { 50 int mid, s = 0, x = 1, y = min(min(i, n - i + 1), min(j, m - j + 1));//二分半径 51 while(x <= y) 52 { 53 mid = (x + y) >> 1; 54 if(pd(i, j, mid)) s = mid, x = mid + 1; 55 else y = mid - 1; 56 } 57 return s; 58 } 59 60 int main() 61 { 62 int i, j, k, x; 63 n = read(); 64 m = read(); 65 n = n << 1 | 1; 66 m = m << 1 | 1; 67 for(i = 2; i <= n; i += 2) 68 for(j = 2; j <= m; j += 2) 69 { 70 x = read(); 71 for(k = 0; k < 4; k++) sum[k][i][j] = x; 72 } 73 base1[0] = base2[0] = 1; 74 for(i = 1; i <= n; i++) base1[i] = base1[i - 1] * bs1; 75 for(i = 1; i <= m; i++) base2[i] = base2[i - 1] * bs2; 76 for(i = 1; i <= n; i++) 77 for(j = 1; j <= m; j++) 78 sum[0][i][j] += sum[0][i - 1][j] * bs1; 79 for(i = 1; i <= n; i++) 80 for(j = 1; j <= m; j++) 81 sum[0][i][j] += sum[0][i][j - 1] * bs2; 82 for(i = 1; i <= n; i++) 83 for(j = m; j; j--) 84 sum[1][i][j] += sum[1][i - 1][j] * bs1; 85 for(i = 1; i <= n; i++) 86 for(j = m; j; j--) 87 sum[1][i][j] += sum[1][i][j + 1] * bs2; 88 for(i = n; i; i--) 89 for(j = 1; j <= m; j++) 90 sum[2][i][j] += sum[2][i + 1][j] * bs1; 91 for(i = n; i; i--) 92 for(j = 1; j <= m; j++) 93 sum[2][i][j] += sum[2][i][j - 1] * bs2; 94 for(i = n; i; i--) 95 for(j = m; j; j--) 96 sum[3][i][j] += sum[3][i + 1][j] * bs1; 97 for(i = n; i; i--) 98 for(j = m; j; j--) 99 sum[3][i][j] += sum[3][i][j + 1] * bs2; 100 for(i = 1; i <= n; i++) 101 for(j = 1; j <= m; j++) 102 if((i ^ j ^ 1) & 1) 103 ans += work(i, j) >> 1; 104 printf("%d\n", ans); 105 return 0; 106 }
View Code
Manacher的话,学完再搞吧。
转载于:https://www.cnblogs.com/zhenghaotian/p/6863532.html
[luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)相关推荐
- bzoj 1414 bzoj 3705: [ZJOI2009]对称的正方形(二维Hash)
1414: [ZJOI2009]对称的正方形 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 727 Solved: 345 [Submit][St ...
- BZOJ 1567: [JSOI2008]Blue Mary的战役地图 矩阵二维hash
1567: [JSOI2008]Blue Mary的战役地图 Description Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提 ...
- BZOJ1567 [JSOI2008]Blue Mary的战役地图(二分+二维hash)
题意 问边长为n的两个正方形中最大的相等子正方形.(n<=50) 题解 用到了二维hash,感觉和一维的不太一样. 对于列行有两个不同的进制数然后也是通过类似前缀和的方法差分出一个矩形的hash ...
- BZOJ2351[BeiJing2011]Matrix——二维hash
题目描述 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过. 所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参 ...
- NEUQ 2015: Bitmap(二维hash)
题目链接 题意 给一个N×NN × NN×N的矩阵问包含多少个M×MM×MM×M的子矩阵,子矩阵不一定完全相同,同时加上某个数相同也算 思路 首先差分,这样就可以直接找匹配的矩阵. 二维hash+容斥 ...
- bzoj 2351: [BeiJing2011]Matrix(二维Hash)
2351: [BeiJing2011]Matrix Time Limit: 20 Sec Memory Limit: 128 MB Submit: 938 Solved: 303 [Submit] ...
- 小程序生成二维码,正方形二维码,跟小程序码
data:{ qrimg: " ", showCodeImg:true, } wx.request({ url: app.globalData.siteurlh5 +'/api/a ...
- Matrix(二维hash)
题目链接 文章目录 题目描述 题意: 题解 代码: 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K 64bit IO Format: %lld 题目 ...
- 【bzoj1047】[HAOI2007]理想的正方形 二维RMQ
题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...
最新文章
- c++主线程等待子线程结束_简单明了的 Python 多线程来了 | 原力计划
- Redis——由分布式锁造成的重大事故
- div设置宽度,实现不等比缩放,或设置最小宽度 min-width
- php微信公众号的服务器配置,微信公众号服务器配置选项PHP示例代码
- 面试官、女朋友都满意系列 - 决策树
- vs code的tabs模式的终端
- python 与或非_Python的阶乘求和
- java的内部字符编码
- android studio线性渐变,使用Kotlin实现文字渐变TextView的代码
- mysql sql常用语句大全
- Centos/Linux 源码安装wireshark与tshark任意版本
- 《Dive Into Deeping Learing》学习笔记:深度学习基础
- 关闭webstorm提示 empty tag doesn't work in some browsers
- 本地IIS启动后网页HTTP 错误 404.3 - Not Found解决方案
- 【量化投资】03.量化工程abu学习之量化基础(1/3)
- 普通数字到科学计数法的转换
- `inlineCollapsed` not control Menu under Sider. Should set `collapsed` on Sider instead.
- PHP导出Excel文件时导出列的数字长度太长时显示不完整或者乱码显示
- sharepoint显示不正常_正常的吸气和呼吸、异常的呼气丨胸部HRCT表现
- 疫情后的第三年:时代更迭下的技术管理与团队协作
热门文章
- linux下makefile中cp,make与makefile 的理解
- 为对象分配内存TLAB
- linux history操作的路径,绝对路径和相对路径,目录命令(cd,mkdir,rm,history)
- 说实话,用完Gradle之后,有点嫌弃Maven了。贼好用!
- 程序员如何快速消除自己的知识短板?
- 由浅入深,聊聊权限设计
- 树莓派IO口驱动代码的编写、微机总线地址、物理地址、虚拟地址、BCM2835芯片手册
- [python进阶]12.继承的优缺点
- java例子:九九乘法表
- 陌生人社会_陌生人之旅