看题传送门: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. LeetCode Implement strStr()(Sunday算法)

    LeetCode解题之Implement strStr() 原题 实现字符串子串匹配函数strStr(). 假设字符串A是字符串B的子串.则返回A在B中首次出现的地址.否则返回-1. 注意点: - 空 ...

  2. 关于ajax访问express服务器的跨域问题

    在学习es6的时候用promise封装了一个ajax <script type="text/javascript"> function getNews(URL) { l ...

  3. JS实现下拉菜单的功能

    <!DOCTYPE html> <html> <head> <meta charset = "utf8"> <title> ...

  4. 【Django】ContentType组件

    目录 理解 表结构 使用 @ 好,现在我们有这样一个需求,我们的商城里有很多的商品,然而节日要来了,我们要搞活动. 那么,我们就要设计优惠券,优惠券都有什么类型呢?满减的.折扣的.立减的.等等等... ...

  5. Java&amp;Xml教程(九)Java中通过XSD校验XML合法性

    Java XML校验API可以通过XSD(XML Schema Definition)校验XML文件内容的合法性. 在以下的案例中使用javax.xml.validation.Validator 类通 ...

  6. 细说 iOS 消息推送

    APNS的推送机制 与Android上我们自己实现的推送服务不一样,Apple对设备的控制很严格.消息推送的流程必需要经过APNs: 这里 Provider 是指某个应用的Developer,当然假设 ...

  7. win7-时间更新

    今天发现电脑的时间不对,后来就自己摸索了时间的自动更新方法.自己记录下来,以方便以后忘了查询 点击电脑右下角的时间->选择更改日期和时间设置->选择internet->更改设置-&g ...

  8. JavaScript中的global对象,window对象以及document对象的区别和联系

    JavaScript中的global对象,window对象以及document对象的区别和联系 一.概念区分:JavaScript中的global对象,window对象以及document对象 1.g ...

  9. 26.多线程join detach

    #include <iostream> #include <thread> #include <array> #include <Windows.h> ...

  10. Sql延时

    IF EXISTS(SELECT * FROM sys.procedures WHERE name='usp_wait30s')BEGIN DROP PROC usp_wait30sENDgocrea ...