Seek the Name, Seek the Fame
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 24077 | Accepted: 12558 |
Description
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
Restrictions: Only lowercase letters may appear in the input. 1 <= Length of S <= 400000.
Output
Sample Input
ababcababababcabab aaaaa
Sample Output
2 4 9 18 1 2 3 4 5
Source
找公共前后缀的最大长度
比如第一个样列,
ababcababababcabab
a
b
a
b
c
a
b
a
b
a
b
a
b
c
a
b
a
b
公共前后缀有:
- ababcababababcabab a b a b c a b a b a b a b c a b a b
- ababcabab a b a b c a b a b
- abab a b a b
- ab a b
长度分别是 18 9 4 2
next数组记录的其实就是最长公共前后缀的长度
next[i]:字符串 0 到 i 的最长公共前后缀的长度
比如这个样列:
ababcababababcabab
a
b
a
b
c
a
b
a
b
a
b
a
b
c
a
b
a
b
i | next [ i ] |
---|---|
0 | next [ 0 ] = -1 |
1 | next [ 1 ] = 0 |
2 | next [ 2 ] = 0 |
3 | next [ 3 ] = 1 |
4 | next [ 4 ] = 2 |
5 | next [ 5 ] = 0 |
6 | next [ 6 ] = 1 |
7 | next [ 7 ] = 2 |
8 | next [ 8 ] = 3 |
9 | next [ 9 ] = 4 |
10 | next [ 10 ] = 3 |
11 | next [ 11 ] = 4 |
12 | next [ 12 ] = 3 |
13 | next [ 13 ] = 4 |
14 | next [ 14 ] = 5 |
15 | next [ 15 ] = 6 |
16 | next [ 16 ] = 7 |
17 | next [ 17 ] = 8 |
18 | next [ 18 ] = 9 |
得到 next 数组之后,我们从 i=18 开始,
i=18记录 18next[18]=9
i
=
18
记
录
18
n
e
x
t
[
18
]
=
9
i=9记录 9next[9]=4
i
=
9
记
录
9
n
e
x
t
[
9
]
=
4
i=4记录 4next[4]=2
i
=
4
记
录
4
n
e
x
t
[
4
]
=
2
i=2记录 2next[2]=0
i
=
2
记
录
2
n
e
x
t
[
2
]
=
0
i=0结束
i
=
0
结
束
18,9,4,2 18 , 9 , 4 , 2
答案就是2 4 9 18
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<iostream>
using namespace std;
const int MAXN=400000+7;
char s[MAXN];
int slen,nex[MAXN];
void GetNext()
{
int i,j;
i=0;
j=nex[0]=-1;
while(i<slen)
{
while(-1!=j && s[i] != s[j]) j=nex[j];
nex[++i]=++j;
}
}
int main()
{
while(~scanf("%s", s))
{
slen=strlen(s);
GetNext();
stack<int> sta;
// for(int i=0;i<=slen;i++)
// printf("next[%2d]:%2d\n",i,nex[i]);
for(int i=slen;~i;i=nex[i])
if(i>0)
{
// printf("next[%2d]:%2d\n",i,nex[i]);
sta.push(i);
}
while(sta.size())
{
printf("%d ",sta.top());
sta.pop();
}
printf("\n");
}
return 0;
}