在Power String中,求一个字符串的循环节,应满足L mod (L-next[L])=0,则循环节长度为L-next[L]
存在另一种形式的循环节,例如abcabca,此时如果将abc重写三次,得到abcabcabc,则原字符串为其前缀.
此时对于原字符串,其循环节长度为L-next[L]=7-4=3,循环节为abc.具体可见下面这个题
[Baltic2009]Radio Transmission
给你一个字符串,它是由某个字符串不断自我连接形成的。 但是这个字符串是不确定的,现在只想知道它的最短长度是多少.
Input
第一行给出字符串的长度,1 < L ≤ 1,000,000. 第二行给出一个字符串,全由小写字母组成.
Output
输出最短的长度
Sample Input
8
cabcabca
Sample Output
3
HINT
对于样例,我们可以利用"abc"不断自我连接得到"abcabcabc",读入的cabcabca,是它的子串
#include <cstdio> #define MAXN 1000002 using namespace std; char s[MAXN]; int next[MAXN]; int n; void solve() { next[1] = 0; int j = 0; for (int i = 2; i <= n; i ++) { while ((j) && (s[j + 1] != s[i])) j = next[j]; if (s[j + 1] == s[i]) j ++; next[i] = j; } printf("%d\n", n - next[n]); } int main() { scanf("%d\n%s", &n, s + 1); solve(); return 0; }
对于Milking Gird
Sol:
将大矩阵的每一列看成一个字符,然后对该大矩阵的每一列求出next[i],则列最短循环节长度=小矩阵的宽=ans1=c-next[c]。
将大矩阵的每一行看成一个字符,然后对该大矩阵的每一行求出next[j],则行最短循环节长度=小矩阵的高=ans2=r-next[r]。
最后答案:ans1*ans2即为所求矩阵的面积。
#include<bits/stdc++.h> using namespace std; char s[10010][100]; int next[10010]; int r,c; bool str1(int i,int j)//判断第i行和第j行是否相等 { for(int k=0;k<c;k++) if(s[i][k]!=s[j][k]) return false; return true; } bool str2(int i,int j)//判断第i列和第j列是否相等 { for(int k=0;k<r;k++) if(s[k][i]!=s[k][j]) return false; return true; } int main() { while(scanf("%d%d",&r,&c)==2) { for(int i=0;i<r;i++) scanf("%s",s[i]); next[0]=next[1]=0; for(int i=1;i<r;i++)//把每行看成一个字符 { int j=next[i]; while(j && str1(i,j)==false) j=next[j]; next[i+1] = (str1(i,j)==true)? j+1 :0; } int ans1=r-next[r]; next[0]=next[1]=0; for(int i=1;i<c;i++)//把每列看成一个字符 { int j=next[i]; while(j && str2(i,j)==false) j=next[j]; next[i+1] = (str2(i,j)==true)? j+1 :0; } int ans2=c-next[c]; printf("%d\n",ans1*ans2); } } //原文链接:https://blog.csdn.net/u013480600/article/details/22990715
原文地址:https://www.cnblogs.com/cutemush/p/12301822.html
时间: 2024-10-10 10:19:21