KMP的next数组应用。一句话,next[j]必须为满足str[1..next[j]] = str[j-next[j]+1..j]的最大值。
以abababa为例,next[7] = 5,则 str[1..5] = str[3..7],显然str[3..5] = str[5..7]。
next[5] = 3,则 str[1..3] = str[3..5],根据上面所得可知str[1..3] = str[5..7]。
由于next数组的性质,显然上述对任意情况都是成立的,每个next保存的值都可使str[1..next[j]] = str[len-next[j]+1..len]。
这里我们只需要从len到1找出next的非零值,再倒序输出就可以了。
code:
#include<cstdio>
#include<cstring>
char str[400001] ;
int next[400001] ;
int ans[400001] ;
int len ;
void get_next(){//根据已知next推出
next[1] = 0 ;
int j = 0 ;
for(int i=2; i<=len; i++){
while(j>0&&str[j+1]!=str[i])
j = next[j] ;
if(str[j+1]==str[i]) j ++ ;
next[i] = j ;
}
}
int main(){
int i, j ;
while(~scanf("%s", str+1)){
len = strlen(str+1) ;
get_next() ;
ans[0] = i = len ;
j = 1 ;
while(next[i]>0){
ans[j++] = next[i] ;
i = next[i] ;
}
for(i=j-1; i>=0; i--)
printf("%d ", ans[i]) ;
printf("\n") ;
}
return 0 ;
#include<cstring>
char str[400001] ;
int next[400001] ;
int ans[400001] ;
int len ;
void get_next(){//根据已知next推出
next[1] = 0 ;
int j = 0 ;
for(int i=2; i<=len; i++){
while(j>0&&str[j+1]!=str[i])
j = next[j] ;
if(str[j+1]==str[i]) j ++ ;
next[i] = j ;
}
}
int main(){
int i, j ;
while(~scanf("%s", str+1)){
len = strlen(str+1) ;
get_next() ;
ans[0] = i = len ;
j = 1 ;
while(next[i]>0){
ans[j++] = next[i] ;
i = next[i] ;
}
for(i=j-1; i>=0; i--)
printf("%d ", ans[i]) ;
printf("\n") ;
}
return 0 ;
}