【URAL 1486】Equal Squares

题意:求给定字符矩阵中相同正方形矩阵的最大边长和这两个相同正方形的位置

第一次写字符串哈希,选两个不同的模数进行二维字符串哈希。

本来应该取模判断相等后再暴力扫矩阵来判断,但是我看到《Hash在信息学竞赛中的一类应用》中这么写道:

于是我还会再次判重吗?肯定不会!!!

于是这样写完后就调啊调,调出几个像没用unsigned long long这样的脑残错误后交上去就A了233

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef unsigned long long ll;
const int N = 503;
const ll p = 100007;
const int p1 = 1007;
const int p2 = 10007;

struct node {
	ll to; int nxt, x, y;
	node (ll _to = 0, int _nxt = 0, int _x = 0, int _y = 0) : to(_to), nxt(_nxt), x(_x), y(_y) {}
} E[N * N];

char s[N][N];
int point[p + 3], cnt, n, m;
ll hash1[N][N], hash[N][N], pow1[N], pow2[N];

void ins(ll from, ll to, int x, int y) {E[++cnt] = node(to, point[from], x, y); point[from] = cnt;}
int __(ll t) {
	ll f = t % p;
	for(int i = point[f]; i; i = E[i].nxt)
		if (E[i].to == t) return i;
	return 0;
}
bool _(int t) {
	memset(point, 0, sizeof(point)); cnt = 0;
	ll num;
	for(int i = 1; i <= n - t + 1; ++i)
		for(int j = 1; j <= m - t + 1; ++j) {
			num = hash[i + t - 1][j + t - 1] - hash[i + t - 1][j - 1] * pow1[t] - hash[i - 1][j + t - 1] * pow2[t] + hash[i - 1][j - 1] * pow1[t] * pow2[t];
			if (__(num)) return 1;
			ins(num % p, num, i, j);
		}
	return 0;
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) scanf("%s", s[i] + 1);
	pow1[0] = 1; pow2[0] = 1;
	for(int i = 1; i < N; ++i) pow1[i] = pow1[i - 1] * p1, pow2[i] = pow2[i - 1] * p2;
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= m; ++j) {
			hash1[i][j] = hash1[i][j - 1] * p1 + (int) s[i][j];
			hash[i][j] = hash[i - 1][j] * p2 + hash1[i][j];
		}
	int left = 0, right = n == m ? n - 1 : min(n, m), mid;
	while (left < right) {
		mid = (left + right + 1) >> 1;
		if (_(mid)) left = mid;
		else right = mid - 1;
	}
	if (left == 0) puts("0");
	else {
		printf("%d\n", left);
		memset(point, 0, sizeof(point)); cnt = 0;
		for(int i = 1; i <= n - left + 1; ++i)
			for(int j = 1; j <= m - left + 1; ++j) {
			ll num = hash[i + left - 1][j + left - 1] - hash[i + left - 1][j - 1] * pow1[left] - hash[i - 1][j + left - 1] * pow2[left] + hash[i - 1][j - 1] * pow1[left] * pow2[left];
			if (right = __(num)) {
				printf("%d %d\n%d %d\n", E[right].x, E[right].y, i, j);
				return 0;
			}
			ins(num % p, num, i, j);
		}
	}

	return 0;
}

神奇的哈希啊,我到现在都对你的时间复杂度感到迷茫~

时间: 2024-10-17 18:02:19

【URAL 1486】Equal Squares的相关文章

【Ural 1057】幂和的数量

[题目描述] 写一个程序来计算区间[X,Y]内满足如下条件的整数个数:它恰好等于K个互不相等的B的整数幂之和. 举个例子.令X=15,Y=20,K=2,B=2.在这个例子中,区间[15,20]内有3个整数恰好等于两个互不相等的2的整数幂之和: 17=2^4+2^0 18=2^4+2^1 20=2^4+2^2 [输入格式] 输入文件的第一行有两个空格隔开的整数X,Y(1<=X<=Y<=2^31-1). 第二行有两个整数K,B(1<=K<=20,2<=B<=10).

【URAL 1519】【插头dp模板】Formula 1

1519. Formula 1 Time limit: 1.0 second Memory limit: 64 MB Background Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic games of 20**, it is well-known, that the city will conduct one of the Formula 1 events. Surely

【URAL 1297】Palindrome 最长回文子串

模板题,,,模板打错查了1h+QAQ #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 1000003; int t1[N], t2[N], c[N], f[N][30]; void st(int *x, int *y, int *sa, int n, int m) { int i; for(i =

【POJ 1739】Tony&#39;s Tour

Tony's Tour Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3545   Accepted: 1653 Description A square township has been divided up into n*m(n rows and m columns) square plots (1<=N,M<=8),some of them are blocked, others are unblocked.

【POJ 3621】Sightseeing Cows

Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7984   Accepted: 2685 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big city! The cows must decide how best to

【赛时总结】◇赛时&#183;V◇ Codeforces Round #486 Div3

◇赛时·V◇ Codeforces Round #486 Div3 又是一场历史悠久的比赛,老师拉着我回来考古了--为了不抢了后面一些同学的排名,我没有做A题 ◆ 题目&解析 [B题]Substrings Sort +传送门+   [暴力模拟] 题意 给出n个字符串,你需要将它们排序,使得对于每一个字符串,它前面的字符串都是它的子串(对于字符串i,则字符串 1~i-1 都是它的子串). 解析 由于n最大才100,所以 O(n3) 的算法都不会爆,很容易想到暴力模拟. 如果字符串i是字符串j的子串

【Matlab开发】函数bsxfun的使用

[Matlab开发]函数bsxfun的使用 版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/lg1259156776/. 说明:当我们想对一个矩阵A的每一列或者每一行与同一个长度相等的向量a进行某些操作(比较大小,乘除等)时,我们只能用循环方法或者利用repmat函数将要操作的向量a复制成和A一样尺寸的矩阵,进而进行操作.从MATLAB R2007a开始,再遇到类似的问题时,我们有了简洁高效的方法,即利用bsxfun函数. bsxfun函数用法 [函数描述]

【C++11】30分钟了解C++11新特性

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明.如果你喜欢这篇文章,请点[推荐].谢谢! 什么是C++11 C++11是曾经被叫做C++0x,是对目前C++语言的扩展和修正,C++11不仅包含核心语言的新机能,而且扩展了C++的标准程序库(STL),并入了大部分的C++ Technical Report 1(TR1)程序库(数学的特殊函数除外). C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto.decl

【线段树】Mayor&#39;s posters

[poj2528]Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 66154   Accepted: 19104 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their elect