hdu 4763 Theme Section kmp

来源:互联网 发布:什么是数据营销 编辑:程序博客网 时间:2024/05/17 05:11

这个next[i]表示的就是最长前后缀,那么头和尾的就不next就可以得出了

那么就剩下判断中间是否存在了,中间的只要不重叠的那部分存在一个next[j]大于的就可以了。

中间的部分是不断扩大的,那么就头尾不断next,中间不断更新新加入的节点即可。

#include <iostream>#include <cstdio>#include <cstring>using namespace std;const int maxn=1e6+9;char a[maxn];int next[maxn];void kmp(char a[],int n){    next[0]=0;    next[1]=0;    for(int i=2;i<=n;i++)    {        int t=i-1;        while(t&&a[i]!=a[next[t]+1])        t=next[t];        next[i]=next[t]+(a[i]==a[next[t]+1]);    }}int solve(int n){    int ans=min(n/3,next[n]);    int l=ans+ans,r=n-ans,ret=0;    for(int i=l;i<=r;i++)    ret=max(ret,next[i]);    while(ans&&ret<ans)    {        ans=next[ans];        ret=max(ret,next[--l]);        ret=max(ret,next[++r]);    }    return ans;}int main(){//    freopen("in.txt","r",stdin);    int T;    scanf("%d",&T);    while(T--)    {        scanf("%s",a+1);        kmp(a,strlen(a+1));        int ans=solve(strlen(a+1));        cout<<ans<<endl;    }    return 0;}