看题传送门: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. linearlayout-weight 属性作用

    今天用到了weight的属性,现在就把这个属性的具体意义记录一下.也是参考网上的讲解,只不过自己验证了一下而已 参考自 http://blog.csdn.net/jincf2011/article/d ...

  2. 怎样通过MSG_WAITALL设置阻塞时间,IO模式精细讲解: MSG_DONTWAIT 、 MSG_WAITALL

    首先给出MSDN上一段设置阻塞超时的代码:(网址为http://social.msdn.microsoft.com/Forums/zh-SG/visualcpluszhchs/thread/3d9da ...

  3. POJ 2433 枚举

    题意: 思路: 每回枚举去哪个山包 枚举的姿势很重要 //By SiriusRen #include <cstdio> #include <algorithm> using n ...

  4. 突破极限 解决大硬盘上安装Unix新思路

    一.问题提出 硬盘越做越大,然我喜欢让我忧.10年前就遇到过在586电脑BIOS不认识超过8.4G容量硬盘的问题,以及Windows Nt操作系统不认大硬盘(容量超过8.4G)的问题,对于Linux ...

  5. Linux下使用SSH、Crontab、Rsync三工具实现数据自动备份

    Linux下使用SSH.Crontab.Rsync三工具实现数据自动备份 作为网管人员大概都无一例外的经历过系统备份,尤其是重要系统的备份.重要数据库系统的备份工作.由于备份是个频繁而琐碎的工作,如何 ...

  6. array01.js

    //1.获取指定范围内的随机数 function getRadomNum(min,max){ return Math.floor(Math.random() * (max - min + 1)) + ...

  7. shell项目-分发系统-expect讲解

    shell项目-分发系统-expect讲解 yum install -y expect 1. 自动远程登录 #! /usr/bin/expect set host "192.168.133. ...

  8. ios学习之block初探

    1. block概念 block是ios4.0+和Mac osX 10.6以后引进的对C语言的拓展,用来实现匿名函数的特性.所谓匿名函数,也称闭包函数.即同意创建一个暂时的没有指定名称的函数. 最经经 ...

  9. 【项目基础】容器、AOP理论篇

    一.容器(砂锅) 1.概念: 容器是应用server中位于组件和平台之间的接口集合 2.应用: 容器一般位于应用server之内,由应用server负责载入和维护.一个容器仅仅能存在于一个应用serv ...

  10. open阶段的一致性检验(二)

    SQL> select * from v$version where rownum=1; BANNER --------------------------------------------- ...