学到了一手二维哈希,以前只会一维度,就是通过类似前缀和的思想来做
#include<bits/stdc++.h> #define ull unsigned long long using namespace std; typedef long long ll; const int N=555; const int mod=1e9+7; ull base1=131,base2=13131; ull hash1[N][N],hash2[N][N]; ull p1[N],p2[N]; int n,m; char s[N][N]; map<ull,int> m1; void init(){ int i; p1[0]=1,p2[0]=1; for(i=1;i<555;i++){ p1[i]=p1[i-1]*base1; p2[i]=p2[i-1]*base2; } for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ hash1[i][j]=hash1[i][j-1]*base1+s[i][j]-'a'; hash2[i][j]=hash2[i-1][j]*base2+hash1[i][j]; } } } ull cal(int i,int j,int x){ ull tmp=hash2[i+x-1][j+x-1]; tmp-=hash2[i+x-1][j-1]*p1[x]; tmp-=hash2[i-1][j+x-1]*p2[x]; tmp+=hash2[i-1][j-1]*p1[x]*p2[x]; return tmp; } bool check(int x){ int i,j; m1.clear(); for(i=1;i+x-1<=n;i++){ for(j=1;j+x-1<=m;j++){ ull tmp=cal(i,j,x); if(m1[tmp]) return true; else m1[tmp]++; } } return false; } int main(){ cin>>n>>m; int i,j; for(i=1;i<=n;i++){ scanf("%s",s[i]+1); } init(); int l=1,r=min(n,m); while(l<r){ int mid=l+r+1>>1; if(check(mid)) l=mid; else r=mid-1; } cout<<l<<endl; }