自己yy了好久,终于打出了2维哈希求循环节
这个题解在主要思路就是降维
就是把2维降成1维处理
我们就分析一下下面这个情况
ABCDEA
AAAABA
不难看出,这个的答案是10
我们怎么降维呢???
首先,这个数据有2行
我们想办法把它变成1行
(直接对每一列哈希一下即可)
得到每一列的哈希值,组成一个一维
再利用哈希求最小循环节求出ans1
这样我们就解决了在列上的最小循环节
只需要再求出行上面的最小循环节ans2即可
(ans2求法和ans1求法同理)
最终答案=ans1*ans2
#include<bits/stdc++.h>
using namespace std;
long long r,c,ans=1,k=1e9+7,p[100005],s[100005],f[100005];
string t,a[10004];
int main() {
p[0]=1;
for(long long i=1; i<=100000; i++)
p[i]=p[i-1]*k;
cin>>r>>c;
for(int i=1; i<=r; i++) {
cin>>a[i];
a[i]=' '+a[i];
}
for(int i=1; i<=c; i++)
for(int j=1; j<=r; j++)
f[i]=f[i]*k+a[j][i];
for(long long i=1; i<=c; i++)
s[i]=s[i-1]*k+f[i];
for(long long i=1; i<=c; i++) {
long long kk=i+1;
while(kk+i-1<=c&&s[kk+i-1]-s[kk-1]*p[i]==s[i])
kk+=i;
if(c-kk+1<i&&s[c]-s[kk-1]*p[c-kk+1]==s[c-kk+1]) {
ans=i;
break;
}
}
memset(f,0,sizeof(f));
for(int i=1; i<=c; i++)
for(int j=1; j<=r; j++)
f[j]=f[j]*k+a[j][i];
for(long long i=1; i<=r; i++)
s[i]=s[i-1]*k+f[i];
for(long long i=1; i<=r; i++) {
long long kk=i+1;
while(kk+i-1<=r&&s[kk+i-1]-s[kk-1]*p[i]==s[i])
kk+=i;
if(r-kk+1<i&&s[r]-s[kk-1]*p[r-kk+1]==s[r-kk+1]) {
cout<<ans*i<<endl;
return 0;
}
}
return 0;
}
%%%一样的思路