KMP【UVA1328】 Period
Description
如果一个字符串S是由一个字符串T重复K次形成的,则称T是S的循环节。使K最大的字符串T称为S的最小循环节,此时的K称为最大循环次数。
现给一个给定长度为N的字符串S,对S的每一个前缀S[1~i],如果它的最大循环次数大于1,则输出该前缀的最小循环节长度和最大循环次数。
Input
输入包含多组数据,每组数据第一行为正整数n(2≤n≤1000000),第二行为一个字符串S。
输入结束标志为n=0
Output
输出: 对于每组数据,按照从小到大的顺序输出每个i和对应的K,一对整数占一行。
\(KMP\)的好题啊。
为什么会是\(KMP\)?
考虑这个串是给定的,必然循环的一个串,我们还需要找到的是所有前缀串的最大循环次数。
由于是一个循环串,那么其前缀和后缀必然相等.所以我们考虑到了\(KMP\)算法.
如何解?
想到了是\(KMP\)算法,但是我们不可能直接通过判断当前\(i\ % \ next[i]==0\)来解决此题(样例都出不来好吧.)
考虑一下我们\(next\)数组的定义:
最长公共前后缀的长度.
注意这个\(next\)数组长度不可能为原串长度.
(这就能体现出你\(KMP\)学的怎么样了)
这时考虑\(i-next[i]\)代表着什么。
\(i-next[i]\)代表循环节长度.
为什么?
我们对于一个循环串输出一下其\(next\)数组.
这样

因为我们用\(i-next[i]\)即可求出循环节的长度.
又因为\(next\)数组记录的是最长的.因此这个循环节一定是最短的.
代码
#include<cstdio>
#include<cstring>
#define R
using namespace std;
char s[1000008];
int n,nex[1000008],len,cas;
int main()
{
	while(~scanf("%d",&n))
	{
		if(n==0)break;
		scanf("%s",s+1);
		int k=0;nex[1]=0;
		printf("Test case #%d\n",++cas);
		for(R int i=2;i<=n;i++)
		{
			while(k and s[k+1]!=s[i])k=nex[k];
			if(s[k+1]==s[i])k++;
			nex[i]=k;
		}
		for(R int i=1;i<=n;i++)
			printf("%d ",nex[i]);
		puts("");
		for(R int i=2;i<=n;i++)
		{
			if(nex[i]==i)continue;
			if(i%(i-nex[i])==0 and i/(i-nex[i])>1)
			printf("%d %d\n",i,i/(i-nex[i]));
		}
		memset(nex,0,sizeof nex);
		puts("");//注意这里还有一个换行
	}
}
												
											KMP【UVA1328】 Period的更多相关文章
- 【题解】PERIOD - Period [POJ1961] [SP263]
		
[题解]PERIOD - Period [POJ1961] [SP263] 在进入这道题之前,我们需要了解 kmp 算法 不知道的童鞋可以去看一下Silent_EAG(一个可爱的女孩纸)的讲解. 关于 ...
 - KMP和扩展KMP【转】
		
这种东西基本上在纸上自己推导一下就能做出来XD 转发注明出处 KMP 给出两个字符串A(称为模板串)和B(称为子串),长度分别为lenA和lenB,要求在线性时间内,对于每个A[i] (0<=i ...
 - 【POJ1961】period
		
[POJ1961]period 题目描述 如果一个字符串S是由一个字符串T重复K次构成的,则称T是S的循环元.使K出现最大的字符串T称为S的最小循环元,此时的K称为最大循环次数. 现在给定一个长度为N ...
 - KMP【模板】 && 洛谷 P3375
		
题目传送门 解题思路: 首先说KMP的作用:对于两个字符串A,B(A.size() > B.size()),求B是否是A的一个字串或B在A里的位置或A里有几个B,说白了就是字符串匹配. 下面创设 ...
 - 【UVA1371】Period (二分+DP)
		
题意: 给出两个字符串A,B将B分解成若干个子字符串,然后每个子字符串都要经过编辑变成字符串A,所有子串中编辑最多的次数即为当前状态下的最大编辑次数,要求求最小的最大编辑次数. 编辑操作包括修改.删除 ...
 - 【BZOJ】1355 [Baltic2009]Radio Transmission
		
[算法]KMP [题解]KMP中n-next[n]得到最小循环节的性质. 考虑一个循环串(最后一个循环节可能残缺),它最长的[后缀=前缀]一定是以第二个循环节为起始位置的后缀. 正着考虑的话假设后缀T ...
 - 【CAIOJ1177】 子串是否出现
		
[题目链接] 点击打开链接 [算法] KMP [代码] #include<bits/stdc++.h> using namespace std; #define MAXA 1000010 ...
 - 【POJ2406】 Power Strings (KMP)
		
Power Strings Description Given two strings a and b we define a*b to be their concatenation. For exa ...
 - 【POJ2406】【KMP】Power Strings
		
Description Given two strings a and b we define a*b to be their concatenation. For example, if a = & ...
 
随机推荐
- iOS笔记053- Quartz2D-练习
			
1.水印处理 给图片添加文字.图片水印 // 水印处理 - (void)shuiyin { // 水印处理 UIImage *image = [UIImage imageNamed:@"4 ...
 - 使用Ghost版本Windows7系统下载安装virtualBox和centos7异常解决
			
使用Ghost版本Windows7系统下载安装virtualBox和centos7异常解决: 下载安装运行virtualBox时出现获取VirtualBox对象严重错误(如图): 解决方案步骤: 在开 ...
 - PAT——甲级1009:Product of Polynomials;乙级1041:考试座位号;乙级1004:成绩排名
			
题目 1009 Product of Polynomials (25 point(s)) This time, you are supposed to find A×B where A and B a ...
 - java细节篇(==和equals的区别)
			
1)当==两边是对象时(String,Integer...),两边比的都是地址2)当==两边是基本类型时(int,float),两边比的都是值3)默认equals比的是对象的地址,但是重写的话可以改变 ...
 - 虚函数&&虚继承
			
如果说没有虚函数的虚继承只是一个噩梦的话,那么这里就是真正的炼狱.这个C++中最复杂的继承层次在VS上的实现其实我没有完全理解,摸爬滚打了一番也算得出了微软的实现方法吧,至于一些刁钻的实现方式我也想不 ...
 - lua中如何识别C语言中的struct
			
不如用c写比较简单呢 都要在lua中解析好数据结构,不过也可以用ffi呢...proto.lua
 - idea中新建的web项目不能新建servlet
			
============ ======================================================================== 在新建的“ java ”源文 ...
 - 【bzoj3530】[Sdoi2014]数数  AC自动机+数位dp
			
题目描述 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子串.例如当S=(22,333,0233)时,233是幸运数,2333.20233.3223不是幸运 ...
 - NAT64与DNS64基本原理概述
			
NAT64与DNS64基本原理概述 1.NAT64与DNS64背景 在IPv6网络的发展过程中,面临最大的问题应该是IPv6与IPv4的不兼容性,因此无法实现二种不兼容网络之间的互访.为了实现 ...
 - BZOJ3143 [Hnoi2013]游走  【高斯消元】
			
题目 一个无向连通图,顶点从1编号到N,边从1编号到M. 小Z在该图上进行随机游走,初始时小Z在1号顶点,每一步小Z以相等的概率随机选 择当前顶点的某条边,沿着这条边走到下一个顶点,获得等于这条边的编 ...