题解:P10475 [USACO03FALL] Milking Grid(数据加强版)
题目传送门
思路分析
这道题的一维弱化版是 P4391,没有做过的可以先做弱化版。我们发现这道题只是弱化版的二维模式,所以我们可以先将每一行作为主体,对列做一个 KMP 或者 Hash,求出最短循环节;然后将每一列作为主体,对行做一个 KMP 或者 Hash,最后将两个值相乘就可以得到答案。
AcCode
#include <bits/stdc++.h>
using namespace std;
#define int unsigned long long
const int N=1e4+10,M=100;
const int P=131;
int n,m;
int a[N],b[M];
int nxt1[N],nxt2[M];
char c[N][M];
inline int read(){
int t=0,f=1;
register char c=getchar();
while(c<'0'||c>'9') f=(c=='-')?(-1):(f),c=getchar();
while(c>='0'&&c<='9') t=(t<<3)+(t<<1)+(c^48),c=getchar();
return t*f;
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) cin>>c[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) a[i]=a[i]*P+(int)(c[i][j]-'a'+1);
for(int j=1;j<=m;j++)
for(int i=1;i<=n;i++) b[j]=b[j]*P+(int)(c[i][j]-'a'+1);
for(int i=2,j=0;i<=n;i++){
while(j&&a[j+1]!=a[i]) j=nxt1[j];
if(a[j+1]==a[i]) j++;
nxt1[i]=j;
}
for(int i=2,j=0;i<=m;i++){
while(j&&b[j+1]!=b[i]) j=nxt2[j];
if(b[j+1]==b[i]) j++;
nxt2[i]=j;
}
cout<<(n-nxt1[n])*(m-nxt2[m]);
return 0;
}

浙公网安备 33010602011771号