POJ 2752 Seek the Name, Seek the Fame(KMP 理解应用)

Seek the Name, Seek the Fame
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 9735 Accepted: 4670

Description

The little cat is so famous, that many couples tramp over hill and dale to Byteland, and asked the little cat to give names to their newly-born babies. They seek the name, and at the same time seek the fame. In order to escape from such boring job, the innovative little cat works out an easy but fantastic algorithm: 

Step1. Connect the father's name and the mother's name, to a new string S. 
Step2. Find a proper prefix-suffix string of S (which is not only the prefix, but also the suffix of S). 

Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:) 

Input

The input contains a number of test cases. Each test case occupies a single line that contains the string S described above. 

Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000. 

Output

For each test case, output a single line with integer numbers in increasing order, denoting the possible length of the new baby's name.

Sample Input

ababcababababcabab
aaaaa

Sample Output

2 4 9 18
1 2 3 4 5

Source


这个题目只要对KMP有一定理解就能做了,题目意思是求一个串的所有前缀与后缀相同的串的长度

这个题目看见首先这个串就是一个,而且是最长的

然后就是对这个串求一次next求完之后就是输出结果

结果就是输出next[len]这个肯定不是本身最长的,然后不断next next就OK了

至于为什么这样其实理解了KMP是不难发现的

就拿题目中的串来讲解一下吧!

ababcababababcabab
0: -1 1: 0 2: 0 3: 1 4: 2 5: 0 6: 1 7: 2 8: 3 9: 4 10: 3 11: 4 12: 3 13: 4 14: 5 15: 6 16: 7 17: 8 18: 9 

看18位置的next是9,那么这个是一个答案,因为在位置18前面有9个字符是满足题目的串

然后跳到9的这个位置,发现就是答案,其实结果已经很明显了

18位置的next是9,那么9位置的next值前面的next值个字符和18前面的几个相同,而又与开始的

几个相同,这样就是后缀与前缀相同,就是题目要求的答案了!

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
char str[500000];
int next[500000];
int ans[500000];
int pos;
int get_next(int i,int j)
{
next[0]=-1;
while(str[i])
{
if(j==-1 || str[i]==str[j])
{
j++;
i++;
next[i]=j;
}
else
j=next[j];
}
return i;
}
int main()
{
int i,j,k;
int len;
while(scanf("%s",str)!=EOF)
{
pos=0;
len=get_next(0,-1);
i=next[len];
while(i!=-1)
{
ans[pos++]=i;
i=next[i];
}
for(i=pos-2;i>=0;i--)
printf("%d ",ans[i]);
printf("%d\n",len);
}
return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值