看题传送门:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1027

给定一个长度为n的循环节,求它的每个前缀的最短循环节。换句话说,对于每个i (2<=i<=n),求一个最大的整数K>1(如果k处在),使得s的前i个字符组成的前缀是某个字符串重复K次得到。输出所有存在K的i对应的K。

比如aabaabaabaab只有当 i=2 6 9 12时k存在,且分别为2,2,3,4

分析:

用KMP求得失配函数f为

j: 0  1  2  3  4  5  6  7  8  9  10  11  12

P a  a  b  a  a  b  a  a  b  a    a   b

f 0  0  1  0  1   2  3  4  5  6    7  8    9

可以看出,如果它是一个循环节,那么有 i%(i-f[i])==0

为什么会这样?

KMP原来是模板串和文本串之间的匹配关系,而失配函数是模板串自身(将自身平移f[i],看是否能匹配)这题省略了文本串,可将文本串看做模板串,错位的部分即为i-f[i],如果这i 个组成循环节,那么 i - f[i]这部分必然也是循环节。

为什么这样?下面摘自http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html

-----------------------

-----------------------

k    m        x      j       i

由上,next【i】=j,两段红色的字符串相等(两个字符串完全相等),s[k....j]==s[m....i]

设s[x...j]=s[j....i](xj=ji)

则可得,以下简写字符串表达方式

kj=kx+xj;

mi=mj+ji;

因为xj=ji,所以kx=mj,如下图所示

-------------

-------------

k   m        x     j

看到了没,此时又重复上面的模型了,kx=mj,所以可以一直这样递推下去

所以可以推出一个重要的性质len-next[i]为此字符串的最小循环节(i为字符串的结尾),另外如果len%(len-next[i])==0,此字符串的最小周期就为len/(len-next[i]);

#include<cstdio>
const int MAXN=1000000+10;
char p[MAXN];
int f[MAXN]; void getfail(const int &n)
{
f[0]=f[1]=0;
for(int i=1;i<n;i++)
{
int j=f[i];
while(j > 0 && p[i]!=p[j]) j=f[j];
if(p[i]==p[j]) j++;
f[i+1]=j;
}
} int main()
{
int n;
int kase=1;
while(scanf("%d",&n),n)
{
scanf("%s",p);
getfail(n);
printf("Test case #%d\n",kase++); /*
for(int i=0;i<n;i++)
printf("%d ",f[i]);
printf("\n");
*/
for(int i=0;i<=n;i++)
{
if(f[i] >0 && i%(i-f[i])==0)
printf("%d %d\n",i,i/(i-f[i]));
}
printf("\n");
}
}

LA 3026 - Period KMP的更多相关文章

  1. KMP(fail数组应用) LA 3026 Period

    题目传送门 题意:(训练指南P213) 求每个前缀的最短循环节 分析:利用失配函数的性质,如果i % (i - fail[i]) == 0,那么正好错位移动一个循环节长度. #include < ...

  2. LA 3026 Period

    这只是蓝书上的一道KMP水题...然后对于最长前缀的循环证明我就不说了... #include<iostream> #include<cstring> #include< ...

  3. UVALive - 3026 Period kmp next数组的应用

    input n 2<=n<=1000000 长度为n的字符串,只含小写字母 output Test case #cas 长度为i时的最小循环串 循环次数(>1) 若没有则不输出 做法 ...

  4. Uvalive - 3026 Period (kmp求字符串的最小循环节+最大重复次数)

    参考:http://www.cnblogs.com/jackge/archive/2013/01/05/2846006.html 总结一下,如果对于next数组中的 i, 符合 i % ( i - n ...

  5. 【暑假】[实用数据结构]UVAlive 3026 Period

    UVAlive 3026 Period 题目: Period   Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld ...

  6. LA 3026 && POJ 1961 Period (KMP算法)

    题意:给定一个长度为n字符串s,求它每个前缀的最短循环节.也就是对于每个i(2<=i<=n),求一个最大整数k>1(如果存在),使得s的前i个字符组成的前缀是某个字符串重复得k次得到 ...

  7. UVALive 3026 Period (KMP算法简介)

    kmp的代码很短,但是不太容易理解,还是先说明一下这个算法过程吧. 朴素的字符串匹配大家都懂,但是效率不高,原因在哪里? 匹配过程没有充分利用已经匹配好的模版的信息,比如说, i是文本串当前字符的下标 ...

  8. hdu 1358 period KMP入门

    Period 题意:一个长为N (2 <= N <= 1 000 000) 的字符串,问前缀串长度为k(k > 1)是否是一个周期串,即k = A...A;若是则按k从小到大的顺序输 ...

  9. POJ 1961 Period( KMP )*

    Period Time Limit: 3000MSMemory Limit: 30000K Total Submissions: 12089Accepted: 5656 Description For ...

随机推荐

  1. [易飞]一张领料单单身仓库&quot;飞了&quot;引起的思考

    [摘要]我司每月月初10号前財务要出报表.故10号前要做完毕本月结. PMC经理接到仓管员反馈. 物料-30408011003在账上怎么还有那么多?上次发料的时候已发完. 相应的领料单:5403-20 ...

  2. UICollectionView——整体总结

    前言 这几天有时间看了下UICollectionView的东西,才发觉它真的非常强大,很有必要好好学习学习.以前虽然用过几次,但没有系统的整理总结过.这两天我为UICollectionView做一个比 ...

  3. BZOJ 4582 贪心

    思路: 显然是个贪心 排个序 然后扫几遍就好了 (重叠的区间不能取) //By SiriusRen #include <cstdio> #include <algorithm> ...

  4. OpenCV —— 跟踪与运动

    理解物体运动主要包含两个部分:识别和建模 识别在视频流后续的帧中找出之前某帧镇南关的感兴趣物体 寻找角点 可跟踪的特征点都称为角点,从直观上讲,角点(而非边缘)是一类含有足够信息且能从当前帧和下一帧中 ...

  5. 多行文本溢出显示...的方法(-webkit-line-clamp)

    限制在一个块元素显示的文本的行数. -webkit-line-clamp 是一个 不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中. 为了实现该 ...

  6. 利用JAVA反射机制实现调用私有方法

    1.fragment是AccessibilityFragment的對象.须要被調用的方法的類. setAccessible(true)并非将方法的訪问权限改成了public.而是取消java的权限控制 ...

  7. Cocos2d-x 之大牛看法

    (未完毕) cocos2d-x并非一个适合网游client(mmo)的游戏引擎.越是大型游戏,这个小引擎就越无法驾驭(尽管它很受欢迎). 之前我在原来的公司使用的是自主研发的C3引擎,已经对外开放(尚 ...

  8. ubuntu-12.04工作区内容变换所属工作区

    最近一直纠结于ubuntu12.04窗口更改所属工作区问题,今天在网上看到了方法.记录下来 主要就是利用快捷键. 1.打开你想移动的窗口 2.使用快捷键Shift + Ctrl + Alt + Dow ...

  9. uiautomator——第一个例子:打开浏览器,输入网址

    1.在sdk安装目录:E:\Test_Tools\auto_test\app\adt-bundle-windows-x86-20131030\sdk\tools下启动uiautomatorviewer ...

  10. Angular:内置指令

    [ngIf]表达式结果为真,显示元素:表达式结果为假,移除元素. <div *ngIf="a > b"></div> [ngSwitch]对表达式进行 ...