[日常训练]article

Description

\(Y\)今天来写作文啦!
\(Y\)非常善于堆砌辞藻。在洋洋洒洒写了一长篇之后,小\(Y\)发现作文中很多段落都似曾相识。小\(Y\)认为,如果一段字符在文章开头,结尾和中间都出现过,那么这段字符就可以被认为是一个“经典段”。
现在小\(Y\)给你一篇文章,他想知道最长的一段“经典段”长度是多少?
注意,这里要求经典串至少出现三次,分别作为文章的前缀,后缀,及既非前缀也非后缀。

Input

一行,给出一个由小写字母组成的字符串。

Output

输出满足题目要求的非空子串,如果不存在这样的非空子串输出。(字符串严格匹配,不含双引号)

Sample Input

fixprefixsuffix

Sample Output

fix

HINT

字符串长度\(\leq10^6\)

Solution

\(kmp\)预处理出这个字符串\(a\)能与后缀匹配的前缀最长子串\(b\).

\(nxt[\;]\)数组求出\(b\)中哪些下标\(i\)使得\(b[1..i]\)\(a\)后缀.

\(kmp\)匹配\(a[2...|a|-1]\)\(b\),求出最大的\(i\)使得\(b[1..i]\)\(a\)后缀.

#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 1000005
using namespace std;
int nxt[N],n,ans;
bool f[N];
char a[N],b[N],c[N];
inline void get_nxt(char b[],int n){
    for(int i=2,j=0;i<=n;++i){
        while(j&&b[j+1]!=b[i]) j=nxt[j];
        if(b[j+1]==b[i]) ++j;
        nxt[i]=j;
    }
}
inline void kmp1(){
    int k=0;
    for(int i=1,j=0;i<n;++i){
        while(j&&b[j+1]!=a[i]) j=nxt[j];
        if(b[j+1]==a[i]) ++j;
        if(i==n-1) k=j;
    }
    while(k){
        //printf("k=%d\n",k); 
        f[k]=true;k=nxt[k];
    }
}
inline int kmp2(){
    int ret=0;get_nxt(a,n);
    for(int i=2,j=0;i<n;++i){
        while(j&&c[j+1]!=c[i]) j=nxt[j];
        if(c[j+1]==c[i]) 
            if(f[++j]) ret=max(ret,j);
    }
    return ret;
}
inline void print(){
    printf("Y can't find any classical string.\n");
}
inline void init(){
    scanf("%s",c+1);n=strlen(c+1);
    if(n<3){
        print();return;
    }
    for(int i=n,j=1;i>1;--i,++j)
        b[j]=c[i];
    for(int i=n-1,j=1;i;--i,++j)
        a[j]=c[i];
    get_nxt(b,n-1);kmp1();
    ans=kmp2();
    if(ans){
        for(int i=ans;i;--i)
            printf("%c",b[i]);
        printf("\n");
    }
    else print();
}
int main(){
    freopen("article.in","r",stdin);
    freopen("article.out","w",stdout);
    init();
    fclose(stdin);
    fclose(stdout);
    return 0;
}
posted @ 2016-11-09 23:11  Aireen_Ye  阅读(293)  评论(0编辑  收藏  举报
底部 顶部 留言板 归档 标签
Der Erfolg kommt nicht zu dir, du musst auf den Erfolg zugehen.