看题传送门: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");
}
}

最新文章

  1. 打造一个有感觉的vim(四)
  2. Xmanager远程Centos 7 Xfce
  3. java System.out
  4. Windows-005-显示隐藏文件
  5. 推荐一本书《深入理解PHP内核》
  6. HDU1565 方格取数(1)(状态压缩dp)
  7. thanks使用注意事项;
  8. Javascript知识三
  9. JavaScript(简介)【Javascript历史】
  10. react-native中的setNativeProps
  11. 在mysql命令行下执行sql文件
  12. InnoDB存储引擎文件
  13. .NET组件介绍系列
  14. 转:PrintWriter中write与println方法的区别
  15. 深入理解kafka
  16. 使用openssl生成SSL证书完全参考手册
  17. 【linux】U盘安装启动出现press the enter key to begin the installation process 就不动弹了
  18. Activity 5秒 Broadcast 10秒 Service 20秒
  19. 636. Exclusive Time of Functions 进程的执行时间
  20. 用python爬校花网

热门文章

  1. android-从官网下拉源码(ubuntu)
  2. ajax的使用(一)
  3. 基于 Cookie 的 SSO 中间件 kisso
  4. csdn课堂学习
  5. Extjs, 使用GridPanel出现 Layout run failed
  6. 20亿与20亿表关联优化方法(超级大表与超级大表join优化方法)
  7. 有关cascade的结构体
  8. 教你win7解除阻止程序运行怎么操作
  9. 洛谷 P1313 计算系数
  10. javafx image button