P4287 [SHOI2011] palindromic double

The meaning of problems

Consider for each node \ (X \) Maintenance \ (lastpos_x \) represents \ (X \) first of all a suffix string palindrome \ (len \ leqslant len_x / 2 \) and energy and \ (X \) the last character of the match, after enumeration node palindrome string to determine the legality of that point.

Seeking \ (lastpos_x \) :
If the new node \ (X \) satisfies \ (len_x \ leqslant 2 \) , then the \ (lastpos_x fail_x = \) .
Otherwise, from the \ (x \) father node jump up, you can dance to judge.

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=500010;
int n,ans;
char s[maxn];
struct PA
{
    int last,tot;
    int fail[maxn],len[maxn],lastpos[maxn];
    int ch[maxn][30];
    PA(){tot=1;fail[0]=1;len[1]=-1;}
    inline int getfail(int x,int pos,char* s)
    {
        s[0]='#';
        while(s[pos-len[x]-1]!=s[pos])x=fail[x];
        return x;
    }
    inline void build(char* s,int n)
    {
        s[0]='#';
        for(int i=1;i<=n;i++)
        {
            int c=s[i]-'a';
            int p=getfail(last,i,s);
            if(!ch[p][c])
            {
                int q=++tot;len[q]=len[p]+2;
                int tmp=getfail(fail[p],i,s);
                fail[q]=ch[tmp][c];ch[p][c]=q;
                if(len[q]<=2)lastpos[q]=fail[q];
                else
                {
                    tmp=lastpos[p];
                    while(s[i-len[tmp]-1]!=s[i]||((len[tmp]+2)<<1)>len[q])tmp=fail[tmp];
                    lastpos[q]=ch[tmp][c];
                }
            }
            last=ch[p][c];
        }
    }
}pa;
int main()
{
    //freopen("test.in","r",stdin);
    //freopen("test.out","w",stdout);
    scanf("%d%s",&n,s+1);
    pa.build(s,n);
    for(int i=2;i<=pa.tot;i++)
        if((pa.len[pa.lastpos[i]]<<1)==pa.len[i]&&pa.len[pa.lastpos[i]]%2==0)
            ans=max(ans,pa.len[i]);
    printf("%d",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/nofind/p/12069513.html