POJ2752 Seek the Name, Seek the Fame

Posted autoint

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ2752 Seek the Name, Seek the Fame相关的知识,希望对你有一定的参考价值。

题意

给定一个字符串s,从小到大输出s中既是前缀又是后缀的子串的长度。

 $1 leq |s| leq 400000 $

分析

一道kmp裸题。

设串长为n,且base 0。算出kmp失配指针后,n为最长长度,然后用fail数组往前跳即为答案,因为根据fail数组的含义,f[i]意为找到最长前缀(~f[i]-1)与后缀(~i-1)匹配,然后又因为base 0,所以数组的值都不用加1.要从小到大输出,所以用栈存储。

代码

#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
#include<complex>
#pragma GCC optimize ("O0")
using namespace std;
template<class T> inline T read(T&x){
    T data=0;
    int w=1;
    char ch=getchar();
    while(!isdigit(ch))
    {
        if(ch==‘-‘)
            w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=10*data+ch-‘0‘,ch=getchar();
    return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;

char s[400010];
int f[400010];

int main()
{
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    while(~scanf("%s",s))
    {
        int n=strlen(s);
        f[0]=f[1]=0;
        for(int i=1;i<=n;++i)
        {
            int j=f[i];
            while(j&&s[j]!=s[i])
            j=f[j];
            f[i+1]=s[i]==s[j]?j+1:0;
        }
        stack<int>S;
        int x=n;
        while(x)
        {
            S.push(x);
            x=f[x];
        }
        while(!S.empty())
        {
            printf("%d ",S.top());
            S.pop();
        }
        printf("
");
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

以上是关于POJ2752 Seek the Name, Seek the Fame的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2752 Seek the Name, Seek the Fame

poj2752 Seek the Name, Seek the Fame

poj 2752 Seek the Name, Seek the Fame

POJ 2752 Seek the Name, Seek the Fame [kmp]

POJ2752--Seek the Name, Seek the Fame

poj 2752 Seek the Name, Seek the Fame (KMP纯模版)