蒟蒻求助
查看原帖
蒟蒻求助
461359
huangrenheluogu楼主2023/11/16 12:55

用 hash,O(n3)O(n^3),TLE。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 305, mod1 = 998244353, mod2 = 1e9 + 7, mod3 = 1011451423;
char ch;
int n, m, ans = -1, tem1, tem2, tem3, tem4, inv1, inv2, inv3;
struct num{
	int x, y, z;
	inline void clear(){
		x = y = z = 0;
	}
	inline void mul(){
		x = x * 3 % mod1;
		y = y * 3 % mod2;
		z = z * 3 % mod3;
	}
	inline void div(){
		x = x * inv1 % mod1;
		y = y * inv2 % mod2;
		z = z * inv3 % mod3;
	}
}s[2][N][N], a[N][N], mi[N * N], b[N][N], inv[N * N];
inline num minu(num x, num y){
	x.x = (x.x - y.x + mod1) % mod1;
	x.y = (x.y - y.y + mod2) % mod2;
	x.z = (x.z - y.z + mod3) % mod3;
	return x;
}
inline num add(num x, num y){
	x.x = (x.x + y.x) % mod1;
	x.y = (x.y + y.y) % mod2;
	x.z = (x.z + y.z) % mod3;
	return x;
}
inline num mul(num x, num y){
	x.x = x.x * y.x % mod1;
	x.y = x.y * y.y % mod2;
	x.z = x.z * y.z % mod3;
	return x;
}
inline int ksm(int x, int y, int p){
	int res = 1;
	while(y){
		if(y & 1) res = res * x % p;
		x = x * x % p, y >>= 1;
	}
	return res;
}
inline void init(){
	inv1 = ksm(3, mod1 - 2, mod1);
	inv2 = ksm(3, mod2 - 2, mod2);
	inv3 = ksm(3, mod3 - 2, mod3);
	mi[0] = (num){1, 1, 1};
	mi[1] = (num){3, 3, 3};
	inv[0] = (num){1, 1, 1};
	inv[1] = (num){inv1, inv2, inv3};
	for(int i = 2; i <= n * m; i++){
		mi[i] = mi[i - 1];
		mi[i].mul();
		inv[i] = inv[i - 1];
		inv[i].div();
	}
}
inline int calc(int x, int y){
	return (x - 1) * m + y;
}
inline bool check(int x, int y, int xx, int yy){
	num now1 = mul(minu(add(s[0][x - 1][y - 1], s[0][xx][yy]), add(s[0][x - 1][yy], s[0][xx][y - 1])), inv[calc(x, y) - 1]);
	num now2 = mul(minu(add(s[1][x][y], s[1][xx + 1][yy + 1]), add(s[1][x][yy + 1], s[1][xx + 1][y])), inv[calc(n - xx + 1, m - yy + 1) - 1]);
	return now1.x == now2.x && now1.y == now2.y && now1.z == now2.z;
}
signed main(){
	scanf("%lld%lld", &n, &m);
	init();
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			ch = getchar();
			while(ch != '1' && ch != '0') ch = getchar();
			a[i][j] = (num){(ch - 48) * mi[calc(i, j)].x, (ch - 48) * mi[calc(i, j)].y, (ch - 48) * mi[calc(i, j)].z};	
			b[i][j] = (num){(ch - 48) * mi[calc(n - i + 1, m - j + 1)].x, (ch - 48) * mi[calc(n - i + 1, m - j + 1)].y, (ch - 48) * mi[calc(n - i + 1, m - j + 1)].z};	
			s[0][i][j] = minu(add(add(s[0][i - 1][j], s[0][i][j - 1]), a[i][j]), s[0][i - 1][j - 1]);
		}
	}
	for(int i = n; i ; i--){
		for(int j = m; j ; j--){
			s[1][i][j] = minu(add(add(s[1][i + 1][j], s[1][i][j + 1]), b[i][j]), s[1][i + 1][j + 1]);
		}
	}
	for(int i = 1; i <= n; i++){
		for(int j = 1; j <= m; j++){
			for(int k = 2; k + i - 1 <= n && k + j - 1 <= m; k++){
				if(check(i, j, i + k - 1, j + k - 1)){
					ans = max(ans, k);
				}
			}
		}
	}
	printf("%lld", ans);
	return 0;
}
2023/11/16 12:55
加载中...