题解: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;
}

posted @ 2025-03-29 10:52  ask_silently  阅读(12)  评论(0)    收藏  举报