标签:i++ can 内容 题意 get stream 子串 else 就是
题意:给你一个串,问你满足最大字串既是前后缀,也在字符串除去前后缀的位置中出现过;
思路:我用的是拓展kmp求的前后缀,只用kmp也能解,在字符串2/3的位置后开始遍历,如果用一个maxx保存前2/3的最大的next(kmp),也就是最大字串的前后缀,在与拓展kmp的next[i]进行比较;
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define maxn 1000500
using namespace std;
char t[maxn];
int tlen;
int next1[maxn];
int exnext[maxn];
void get_next()
{
    int j=0,k=-1;next1[0]=-1;
    while(j<tlen)
    {
        if(k==-1||t[k]==t[j])
            next1[++j]=++k;
        else
            k=next1[k];
    }
}
void get_exnext()
{
    int i=0,j,po;
    exnext[0]=tlen;
    while(t[i]==t[i+1]&&i+1<tlen)
        i++;
    exnext[1]=i;
    po=1;
    for(int i=2;i<tlen;i++)
    {
        if(exnext[i-po]+i<exnext[po]+po)
            exnext[i]=exnext[i-po];
        else
        {
            j=exnext[po]+po-i;
            if(j<0)
                j=0;
            while(i+j<tlen&&t[j]==t[j+i])
                j++;
            exnext[i]=j;
            po=i;
        }
    }
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--)
    { int ans=0;
        scanf("%s",t);
        tlen=strlen(t);
        if(tlen<=2)
        {
            printf("0\n");
        }
        else
        {
            get_next();
            get_exnext();
            int z=tlen/3;
            z=tlen-z;
           //cout<<z<<endl;
            int maxx=-1;
            for(int i=0;i<=z;i++)
            {
                maxx=max(next1[i],maxx);
            }
           // cout<<maxx<<endl;
            for(int i=z;i<tlen;i++)
            {
                if(maxx<next1[i])
                    maxx=next1[i];
                if(exnext[i]<=maxx)//答案取拓展kmp的值,因为满足子串前后缀大的不一定满足原串的前后缀大;
                {
                    ans=max(ans,exnext[i]);
                }
            }
        }
        printf("%d\n",ans);
    }
}
---恢复内容结束---
标签:i++ can 内容 题意 get stream 子串 else 就是
原文地址:https://www.cnblogs.com/huangdao/p/9450936.html