uvalive 3026 Period KMP(失配函数)
2014-08-09 13:21
417 查看
题意:
给定一个长度为n的字符串,求它每个前缀的最短循环节。即对于i长前缀,存在一个k(k>1)使得,所有[i/k*(j-1),i/k*j]区间的字符串都相等,(1<=j<=k,i%k==0)。
题解:
我们用到KMP中求失配函数f[i]的方法。f[i]表示状态i失配时转移到得新状态,f[0]=0。我们可以证明当f[i]>0且i%(i-f[i])==0时,i长前缀存在i/(i-f[i])长的循环节。证明方法需要通过f[i]的性质来证明,[0,f[i]]和[i-f[i],f[i]]是相等的,当i%(i-f[i])==0时,我们可以每(i-f[i])分段,分成ci,由于[0,f[i]]和[i-f[i],f[i]]是相等的,所以ci=ci+1,因而上述的求解方法是正确的(当i%(i-f[i])!=0时也可以用相同方式证明不成立)。
代码:
给定一个长度为n的字符串,求它每个前缀的最短循环节。即对于i长前缀,存在一个k(k>1)使得,所有[i/k*(j-1),i/k*j]区间的字符串都相等,(1<=j<=k,i%k==0)。
题解:
我们用到KMP中求失配函数f[i]的方法。f[i]表示状态i失配时转移到得新状态,f[0]=0。我们可以证明当f[i]>0且i%(i-f[i])==0时,i长前缀存在i/(i-f[i])长的循环节。证明方法需要通过f[i]的性质来证明,[0,f[i]]和[i-f[i],f[i]]是相等的,当i%(i-f[i])==0时,我们可以每(i-f[i])分段,分成ci,由于[0,f[i]]和[i-f[i],f[i]]是相等的,所以ci=ci+1,因而上述的求解方法是正确的(当i%(i-f[i])!=0时也可以用相同方式证明不成立)。
代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <iostream> #include <algorithm> #include <queue> #include <map> #include <vector> using namespace std; const int maxn=1e6+10; char a[maxn]; int f[maxn]; int main() { int n,tt=0; while(scanf("%d",&n)!=EOF) { int i,j,k; if(n==0)break; scanf("%s",a); f[0]=f[1]=0; for(i=1;i<n;i++) { j=f[i]; while(j&&a[i]!=a[j])j=f[j]; f[i+1]=a[i]==a[j]?j+1:0; } printf("Test case #%d\n",++tt); for(i=2;i<=n;i++) { if(f[i]>0&&i%(i-f[i])==0)printf("%d %d\n",i,i/(i-f[i])); } printf("\n"); } return 0; }
相关文章推荐
- UVALive 3026 Period KMP 失配函数处理周期的问题
- UVALive - 3026 - Period (KMP)
- UVALive 3026 Period (KMP上的dp,学习ac自动机的前奏)
- Period UVALive - 3026(KMP)
- Period UVALive - 3026(KMP)
- uvaLive 3026 - Period 水KMP循环结
- uvalive3026 Period (KMP+结论)
- UVALive 3026 (LA 3026) Period KMP求字符串周期
- UVALive 3026 Period ( kmp 求前缀最小循环节)
- UVALive 3026 Period(KMP裸)
- Uvalive - 3026 Period (kmp求字符串的最小循环节+最大重复次数)
- LA 3026 Period (KMP失配函数)
- UVALive 3026 period(周期) kmp算法的应用
- UVALive 3026 Period (KMP算法简介)
- [UVALive3026] Period && 字符串
- UVALive 3026(KMP)
- 【暑假】[实用数据结构]UVAlive 3026 Period
- UVALive - 3026:Period
- uvalive 3026 Period (前缀最短循环节)
- 【暑假】[实用数据结构]UVAlive 3026 Period