码迷,mamicode.com
首页 > 其他好文 > 详细

POJ2752 Seek the Name, Seek the Fame

时间:2018-08-24 19:26:08      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:sdi   最长前缀   ons   int   stdout   pop   class   get   数组   

题意

给定一个字符串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("\n");
    }
//  fclose(stdin);
//  fclose(stdout);
    return 0;
}

POJ2752 Seek the Name, Seek the Fame

标签:sdi   最长前缀   ons   int   stdout   pop   class   get   数组   

原文地址:https://www.cnblogs.com/autoint/p/9531516.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!