用 hash,O(n3),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;
}