【二维循环节 字符串hash】 奶牛矩阵
传送门
题意
给定一个\(r\)行\(c\)列的矩阵,求出一个最小覆盖矩阵,即循环节矩阵
即这个矩阵无限扩张后的矩阵能够包含原来的完整矩阵,输出当前矩阵的面积
数据范围
\(\begin{array}{l}1 \leq R \leq 10000 \\ 1 \leq C \leq 75\end{array}\)
题解
\(hash\) 后\(kmp\)分别求所有行最小循环节长度,所有列的最小循环节长度,当前矩阵可能是由部分循环节构成
所以可能是当前不完美的循环节,二者相乘即最小覆盖矩阵。
Code
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define ll long long
#define ull unsigned long long
const int N=1e4+10;
const ull P=13331;
int ne[N];
int r,c;
char s[N][100];
ull h[N*100],p[N];
int get(int d)
{
memset(ne,0,sizeof ne);
int j=0;
rep(i,2,d+1)
{
while(j && h[i]!=h[j+1]) j=ne[j];
if(h[i]==h[j+1]) j++;
ne[i]=j;
}
return d-ne[d];
}
void solve()
{
cin>>r>>c;
rep(i,1,r+1) cin>>s[i]+1;
rep(i,1,r+1) rep(j,1,c+1)
h[i]=h[i]*P + s[i][j];
int ar=get(r);
memset(h,0,sizeof h);
rep(i,1,c+1) rep(j,1,r+1)
h[i]=h[i]*P+s[j][i];
int ac=get(c);
cout<<ac*ar<<endl;
}
int main()
{
solve();
}

浙公网安备 33010602011771号