其他分享
首页 > 其他分享> > [LuoguP4287][SHOI2011]双倍回文(回文自动机)

[LuoguP4287][SHOI2011]双倍回文(回文自动机)

作者:互联网

[LuoguP4287][SHOI2011]双倍回文(回文自动机)

 题面

定义一个字符串为"双倍回文",当且仅当它是回文串,长度为4的倍数,且前一半和后一半的字符串都是回文串。如\(\texttt{abbaabba}\)

给出一个字符串\(S\),求它的最长双倍回文子串的长度。

\(|S|\leq 5 \times 10^5\)

分析

对于PAM上的每个节点,我们维护\(trans\),代表小于等于当前节点串长度一半的最长回文后缀,指向对应后缀的节点.求法和fail基本一样。

int y=t[p].trans;
while(s[pos-len(y)-1]!=s[pos]||(len(y)+2)*2>len(cur)) y=fail(y);
t[cur].trans=t[y].ch[c]; 
//和getfail类似,注意转移过来加了c之后长度为len(y)+2 

然后对于每个节点,判断\(2len(trans(i))\)是否等于当前长度\(len(i)\),且\(4|len(i)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring> 
#define maxn 500000
#define maxc 26
using namespace std;
char s[maxn+5];
struct PAM{
#define fail(x) (t[x].fail)
#define len(x) (t[x].len)
    struct node{
        int ch[maxc];
        int fail;
        int len;
        int trans;
    }t[maxn+5];
    int ptr,last;
    void ini(){
        ptr=1;
        t[0].fail=1;
        t[1].fail=0;
        len(0)=0;
        len(1)=-1;
        last=0;
    } 
    inline int get_fail(int x,int n){
        while(s[n-len(x)-1]!=s[n]) x=fail(x);
        return x;
    }
    void insert(int c,int pos){
        int p=get_fail(last,pos);
        if(t[p].ch[c]==0){
            int cur=++ptr;
            len(cur)=len(p)+2;
            fail(cur)=t[get_fail(fail(p),pos)].ch[c];
            t[p].ch[c]=cur;
            if(len(cur)<=2) t[cur].trans=fail(cur);
            else{
                int y=t[p].trans;
                while(s[pos-len(y)-1]!=s[pos]||(len(y)+2)*2>len(cur)) y=fail(y);
                t[cur].trans=t[y].ch[c]; 
                //和getfail类似,注意转移过来加了c之后长度为len(y)+2 
            }
        }
        last=t[p].ch[c];
    }
    int calc(){
        int ans=0;
        for(int i=2;i<=ptr;i++){
            if(len(t[i].trans)*2==len(i)&&len(i)%4==0) ans=max(ans,len(i));
        }
        return ans;
    }
}T;
int n;
int main(){
    scanf("%d",&n);
    scanf("%s",s+1);
    T.ini();
    for(int i=1;i<=n;i++) T.insert(s[i]-'a',i);
    printf("%d\n",T.calc());
}

标签:ch,cur,int,len,LuoguP4287,fail,SHOI2011,回文
来源: https://www.cnblogs.com/birchtree/p/12391940.html