During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued about who of them could in 300 minutes find a pair of equal squares of the maximal size in a matrix of size N × M containing lowercase English letters. Squares could overlap each other but could not coincide. He who had found a pair of greater size won. Petr walked by, looked at the matrix, said that the optimal pair of squares had sides K, and walked on. Vova and Sasha still cannot find this pair. Can you help them?

Input

The first line contains integers N and M separated with a space. 1 ≤  N,  M ≤ 500. In the next N lines there is a matrix consisting of lowercase English letters, M symbols per line.

Output

In the first line, output the integer K which Petr said. In the next two lines, give coordinates of upper left corners of maximal equal squares. If there exist more than one pair of equal squares of sizeK, than you may output any of them. The upper left cell of the matrix has coordinates (1, 1), and the lower right cell has coordinates (N,  M). If there are no equal squares in the matrix, then output 0.

Example

input output
5 10
ljkfghdfas
isdfjksiye
pgljkijlgp
eyisdafdsi
lnpglkfkjl
3
1 1
3 3

先要对每一个字符串进行哈希预处理,哈希处理后,把哈希的值在根据行数哈希一遍

没存过的就存一遍, 找到有没有相同的,

这个二分还是比较好写的

这个二维哈希就有点懵逼

 #include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std; typedef long long LL;
typedef unsigned long long ull;
typedef pair<int, int> ii;
const int maxn = ;
const ull p = 1e12 + , pt = ; struct h {
ull ha[maxn][maxn], xp[maxn], sz;
void init1(int n) {
sz = n;
xp[] = ;
for (int i = ; i <= sz ; i++)
xp[i] = xp[i - ] * p;
}
void init2(int id, const string &str) {
ha[id][sz] = ;
for (int i = sz - ; i >= ; i--)
ha[id][i] = ha[id][i + ] * p + (str[i] - 'a' + );
}
ull gethash(int id, int st, int len) {
return ha[id][st] - ha[id][st + len] * xp[len];
}
} Hash;
string s[maxn];
map< ull, ii>mp;
int n, m, ans;
ii ans1, ans2;
ull hat[maxn], xpt[maxn];
void initxpt(int n) {
xpt[] = ;
for (int i = ; i <= n ; i++ )
xpt[i] = xpt[i - ] * pt;
}
int check(int x) {
mp.clear();
ull t;
for (int j = ; j + x - < m ; j++ ) {
hat[] = ;
for (int i = ; i <= n ; i++)
hat[i] = hat[i - ] * pt + Hash.gethash(i, j, x);
for (int k = x ; k <= n ; k++) {
t = hat[k] - hat[k - x] * xpt[x];
if (mp.find(t) != mp.end()) {
ans1 = mp[t];
ans2 = ii(k - x + , j + );
return ;
} else mp[t] = ii(k - x + , j + );
}
}
return ;
}
int main() {
cin >> n >> m;
Hash.init1(m);
for (int i = ; i <= n ; i++) {
cin >> s[i];
Hash.init2(i, s[i]);
}
initxpt(n);
ans = ;
int l = , r = min(n, m) + , mid;
while(l <= r) {
mid = (l + r) >> ;
if(check(mid)) {
ans = mid;
l = mid + ;
} else r = mid - ;
}
if(ans) cout << ans << "\n" << ans1.first << " " << ans1.second << "\n" << ans2.first << " " << ans2.second << endl;
else cout << ans << "\n";
return ;
}

URAL - 1486 Equal Squares 二维哈希+二分的更多相关文章

  1. 【URAL 1486】Equal Squares(二维哈希+二分)

    Description During a discussion of problems at the Petrozavodsk Training Camp, Vova and Sasha argued ...

  2. BZOJ1397 : Ural 1486 Equal squares

    二分答案mid,然后检验是否存在两个相同的mid*mid的正方形 检验方法: 首先对于每个位置,求出它开始长度为mid的横行的hash值 然后对于hash值再求一次竖列的hash值 将第二次求出的ha ...

  3. 【BZOJ 2462】矩阵模板 (二维哈希)

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

  4. AcWing - 156 矩阵(二维哈希)

    题目链接:矩阵 题意:给定一个$m$行$n$列的$01$矩阵$($只包含数字$0$或$1$的矩阵$)$,再执行$q$次询问,每次询问给出一个$a$行$b$列的$01$矩阵,求该矩阵是否在原矩阵中出现过 ...

  5. poj-3739. Special Squares(二维前缀和)

    题目链接: I. Special Squares There are some points and lines parellel to x-axis or y-axis on the plane. ...

  6. POJ3690:Constellations(二维哈希)

    Constellations Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 6822   Accepted: 1382 题目 ...

  7. UVA-11019 二维哈希算法

    UVA-11019 题意: 就是给你AB两个字符矩阵,问你B矩阵在A矩阵中的出现次数. 题解:  参考链接:https://blog.csdn.net/qq_38891827/java/article ...

  8. [算法][LeetCode]Search a 2D Matrix——二维数组的二分查找

    题目要求 Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the ...

  9. loj #535. 「LibreOJ Round #6」花火 树状数组求逆序对+主席树二维数点+整体二分

    $ \color{#0066ff}{ 题目描述 }$ 「Hanabi, hanabi--」 一听说祭典上没有烟火,Karen 一脸沮丧. 「有的哦-- 虽然比不上大型烟花就是了.」 还好 Shinob ...

随机推荐

  1. 什么是mysql数据库安全 简单又通俗的mysql库安全简介

    首先我们要了解一下什么是mysql数据库,mysql是目前网站以及APP应用上用的较多的一个开源的关系型数据库系统,可以对数据进行保存,分段化的数据保存,也可以对其数据进行检索,查询等功能的数据库. ...

  2. STM32进阶之串口环形缓冲区实现(转载)

    转载自微信公众号“玩转单片机”,感谢原作者“杰杰”. 队列的概念 在此之前,我们来回顾一下队列的基本概念:队列 (Queue):是一种先进先出(First In First Out ,简称 FIFO) ...

  3. 清华大学《C++语言程序设计基础》线上课程笔记02---类与对象

    类与对象 public是类的对外访问接口: 类内初始值 在定义类时对数据成员写初始值,在创建对象的时候,会使用类内初始值初始化数据成员: class Clock { public: void show ...

  4. 6-C++远征之封装篇[上]-学习笔记

    C++远征之封装篇(上) 课程简介 类(抽象概念),对象(真实具体) 配角: 数据成员和成员函数(构成了精彩而完整的类) 构造函数 & 析构函数(描述了对象的生生死死) 对象复制和对象赋值 ( ...

  5. FZU:1759-Problem 1759 Super A^B mod C (欧拉降幂)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=1759 欧拉降幂是用来干啥的?例如一个问题AB mod c,当B特别大的时候int或者longlong装不下的时 ...

  6. 【Java】关于Spring框架的总结 (二)

    上文提到了 Spring 的 IoC 特性和 AOP 特性,只提到个别的实现方法.本文将对 IoC 和 AOP 其他方法进行讲解. 多种方式实现依赖注入 1.设值注入 上文中使用的注入方法:通过 se ...

  7. wnds更新为1.0

    重画了外观,增加了若干功能,已经上传到码云 https://gitee.com/alan0405/wnds

  8. Plsql developer 怎么在打开时登陆配置oracel client?

    配置前 logon 这块是空白的,该怎么配置呢? 看下面 --> 安装完plsql 后 需要安装 oracle client, 这里不再赘述,请自行百度.下面将贴出如何使用 oracle cli ...

  9. C++各种类型的简单排序大汇总~

    啊,排序的技能点也太多了吧!!!LITTLESUN快要**在排序的技能场了啊!(划掉)经历了两天48小时2880分钟172800秒的艰苦奋斗,终于终于终于学的差不多了!明天就可以去打排序的小怪喽!(撒 ...

  10. deepin linux 安装/启动jeakins报错:处理

    ERROR: No Java executable found in current PATH: /bin:/usr/bin:/sbin:/usr/sbin 安装报错: 1.如还未安装java,则安装 ...