[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
——代码
#include <cstdio>
#include <iostream>
#define UI unsigned int const int MAXN = , bs1 = , bs2 = ;
int n, m, ans;
UI sum[][MAXN][MAXN], base1[MAXN], base2[MAXN]; inline int read()
{
int x = , f = ;
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -;
for(; isdigit(ch); ch = getchar()) x = (x << ) + (x << ) + ch - '';
return x * f;
} inline int min(int x, int y)
{
return x < y ? x : y;
} inline bool pd(int x, int y, int l)
{
UI t, h;
h = sum[][x + l - ][y + l - ]
- sum[][x - l][y + l - ] * base1[l + l - ]
- sum[][x + l - ][y - l] * base2[l + l - ]
+ sum[][x - l][y - l] * base1[l + l - ] * base2[l + l - ];
t = sum[][x + l - ][y - l + ]
- sum[][x - l][y - l + ] * base1[l + l - ]
- sum[][x + l - ][y + l] * base2[l + l - ]
+ sum[][x - l][y + l] * base1[l + l - ] * base2[l + l - ];
if(h ^ t) return ;
t = sum[][x - l + ][y + l - ]
- sum[][x + l][y + l - ] * base1[l + l - ]
- sum[][x - l + ][y - l] * base2[l + l - ]
+ sum[][x + l][y - l] * base1[l + l - ] * base2[l + l - ];
if(h ^ t) return ;
t = sum[][x - l + ][y - l + ]
- sum[][x + l][y - l + ] * base1[l + l - ]
- sum[][x - l + ][y + l] * base2[l + l - ]
+ sum[][x + l][y + l] * base1[l + l - ] * base2[l + l - ];
if(h ^ t) return ;
return ;
} inline int work(int i, int j)
{
int mid, s = , x = , y = min(min(i, n - i + ), min(j, m - j + ));//二分半径
while(x <= y)
{
mid = (x + y) >> ;
if(pd(i, j, mid)) s = mid, x = mid + ;
else y = mid - ;
}
return s;
} int main()
{
int i, j, k, x;
n = read();
m = read();
n = n << | ;
m = m << | ;
for(i = ; i <= n; i += )
for(j = ; j <= m; j += )
{
x = read();
for(k = ; k < ; k++) sum[k][i][j] = x;
}
base1[] = base2[] = ;
for(i = ; i <= n; i++) base1[i] = base1[i - ] * bs1;
for(i = ; i <= m; i++) base2[i] = base2[i - ] * bs2;
for(i = ; i <= n; i++)
for(j = ; j <= m; j++)
sum[][i][j] += sum[][i - ][j] * bs1;
for(i = ; i <= n; i++)
for(j = ; j <= m; j++)
sum[][i][j] += sum[][i][j - ] * bs2;
for(i = ; i <= n; i++)
for(j = m; j; j--)
sum[][i][j] += sum[][i - ][j] * bs1;
for(i = ; i <= n; i++)
for(j = m; j; j--)
sum[][i][j] += sum[][i][j + ] * bs2;
for(i = n; i; i--)
for(j = ; j <= m; j++)
sum[][i][j] += sum[][i + ][j] * bs1;
for(i = n; i; i--)
for(j = ; j <= m; j++)
sum[][i][j] += sum[][i][j - ] * bs2;
for(i = n; i; i--)
for(j = m; j; j--)
sum[][i][j] += sum[][i + ][j] * bs1;
for(i = n; i; i--)
for(j = m; j; j--)
sum[][i][j] += sum[][i][j + ] * bs2;
for(i = ; i <= n; i++)
for(j = ; j <= m; j++)
if((i ^ j ^ ) & )
ans += work(i, j) >> ;
printf("%d\n", ans);
return ;
}
Manacher的话,学完再搞吧。
[luoguP2601] [ZJOI2009]对称的正方形(二维Hash + 二分 || Manacher)的更多相关文章
- BZOJ 1567 Blue Mary的战役地图(二维hash+二分)
题意: 求两个矩形最大公共子正方形.(n<=50) 范围这么小可以枚举子正方形的边长.那么可以对这个矩形进行二维hash,就可以在O(1)的时候求出任意子矩形的hash值.然后判断这些正方形的h ...
- 牛客练习赛1 矩阵 字符串二维hash+二分
题目 https://ac.nowcoder.com/acm/contest/2?&headNav=www#question 解析 我们对矩阵进行二维hash,所以每个子矩阵都有一个额hash ...
- 【BZOJ1414/3705】[ZJOI2009]对称的正方形 二分+hash
[BZOJ1414/3705][ZJOI2009]对称的正方形 Description Orez很喜欢搜集一些神秘的数据,并经常把它们排成一个矩阵进行研究.最近,Orez又得到了一些数据,并已经把它们 ...
- 题解-------[ZJOI2009]对称的正方形
传送门 题目大意 找到所有的上下左右都相同的正方形. 思路:二分+二维Hash 这道题我们首先想到不能暴力判断一个正方形是否合法. 然后我们发现当一个正方形合法时,以这个正方形为中心且比它小的正方形也 ...
- 二维hash
题目描述 给出一个n * m的矩阵.让你从中发现一个最大的正方形.使得这样子的正方形在矩阵中出现了至少两次.输出最大正方形的边长. 输入描述: 第一行两个整数n, m代表矩阵的长和宽: 接下来n行,每 ...
- 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 ...
- bzoj 1414: [ZJOI2009]对称的正方形 manacher算法+單調隊列
1414: [ZJOI2009]对称的正方形 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 331 Solved: 149[Submit][Stat ...
- BZOJ2351[BeiJing2011]Matrix——二维hash
题目描述 给定一个M行N列的01矩阵,以及Q个A行B列的01矩阵,你需要求出这Q个矩阵哪些在原矩阵中出现过.所谓01矩阵,就是矩阵中所有元素不是0就是1. 输入 输入文件的第一行为M.N.A.B,参见 ...
随机推荐
- 使用mfc CHtmlView内存泄露解决方法
第一步,谷歌有文章说CHtmlView部分api使用BSTR没释放: 解决方法是重写一下接口: CString GetFullName() const; CString GetFullName() c ...
- 【思维题 欧拉图】loj#10106. 单词游戏
巧妙的模型转化 题目描述 来自 ICPC CERC 1999/2000,有改动. 有 NNN 个盘子,每个盘子上写着一个仅由小写字母组成的英文单词.你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子 ...
- python元组的相对不可变性
元组与多数python集合(列表.字典.集,等等)一样,保存的是对象的引用.如果引用的元素是可变的,即便元组本身不可变,但是元素依然可变.也就是说元组的不可变性其实是指tuple数据结构的物理内容(即 ...
- Linux菜鸟起飞之路【八】文本编辑器
在Linux中,文本编辑器有两个,VI和VIM.这两个编辑器用法差不多,但vim是vi的升级版,所以功能更强大一些. vim编辑器一共有三种模式,命令行模式.编辑模式和扩展模式. 进入vim界面,首先 ...
- Python爬虫,爬取实验楼全部课程
目的: 使用requests库以及xpath解析进行实验楼所有课程,存入MySQL数据 库中. 准备工作: 首先安装,requests库,lxml库,以及peewee库.在命令行模式,使用以下命令. ...
- PTA 7-2 符号配对
直接用栈模拟即可,数组可做,但因为这节数据结构是栈,为了期末考试还是手写一下栈的操作,值得注意的是,这道题用gets函数在PTA上会编译错误,用scanf("%[^\n]", st ...
- BFS、模拟:UVa1589/POJ4001/hdu4121-Xiangqi
Xiangqi Xiangqi is one of the most popular two-player board games in China. The game represents a ba ...
- poj 1979 走多少个‘ . '问题 dfs算法
题意:给你一个迷宫地图,让你走.问最多可以走多少个“." 思路:dfs 找到起点,然后对起点进行dfs操作. dfs操作时,要把当前的位置标志成"#"表示已经走过,然后进 ...
- emacs设置字体
* C-h f set-default-font set-default-font is an alias for `set-frame-font' in `frame.el'. (set-defau ...
- Centos7 开机显示 ERST: Failed to get Error Log Address Range” 导致无法开机解决方法
开机显示 ERST: Failed to get Error Log Address Range” 导致无法开机,也无法重新安装系统,解决方法:开机进入BIOS , 关闭ACPI选项即可正常开机