Seek the Name, Seek the Fame
作者:互联网
给定一个字符串,要求找到同时是它前缀也是后缀的字符串的个数,并且输出他们的长度。
Input
第一行一个数字N,第二行输入一个字符串,长度<= 10^6.
Output
输出这些子串的结束位置(因为它们的开始位置都是从1开始的),注意每个数字后面有一个空格.
Sample Input
5
aaaaa
Sample Output
1 2 3 4 5
题目大意:找出串中既是前缀又是后缀的所有子串,输出这些子串的结束位置。
如输入:
12
abcabcabcabc
输出:3 6 9 12
sol:先求出所有next[i]的值,将next[i]-i建立一条边,构造fail树,本题是要求整个字串的前缀和后缀的个数,即为完全覆盖,所以我们只需要构造[0,...,next[len],len]的这条链就可以了.
上例next[12]=9,next[9]=6,next[6]=3,next[3]=0。这条链为:0——3(abc)——6(abcabc)——9(abcabcabc)——12(abcabcabcabc)。即前3,6,9,12位分别是该串前缀和后缀的长度。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #define maxn 1000010 6 using namespace std; 7 char s[maxn]; 8 int n,pre[maxn],list[maxn]; 9 int main(){ 10 scanf("%d",&n); 11 scanf("%s",s+1); 12 for (int i=2,j=0;i<=n;i++){ 13 while (j&&s[j+1]!=s[i]) j=pre[j]; 14 if (s[j+1]==s[i]) j++; 15 pre[i]=j; 16 } 17 for (int i=n;i;i=pre[i])//从n开始倒着记录答案 18 list[++list[0]]=i; 19 for (int i=list[0];i>=1;i--) printf("%d ",list[i]);//正着输出 20 printf("\n"); 21 return 0; 22 }
标签:12,Name,后缀,next,maxn,include,Seek,Fame,前缀 来源: https://www.cnblogs.com/cutepota/p/12535197.html