回文自动机

  • 如果不考虑空间回文自动机几乎可以替代 manacher 吧

构造

  • 比较简单,就直接放代码了
const int N=1e6+10;
char S[N];
int n,t[N][26],fail[N],len[N],num[N];
int tot=1,cur,last=0;

inline int getpos(int x,int i) {
    while(i-len[x]-1<1 || S[i-len[x]-1]!=S[i]) x=fail[x];
    return x;
}

signed main(){
    scanf("%s",S+1);
    n=strlen(S+1);
    fail[0]=1;len[1]=-1;
    FOR(i,1,n) {
        if(i>1) S[i]=(S[i]+last-97)%26+97;
        int pos=getpos(cur,i);
        if(!t[pos][S[i]-'a']) {
            fail[++tot]=t[getpos(fail[pos],i)][S[i]-'a'];
            len[tot]=len[pos]+2;
            num[tot]=num[fail[tot]]+1;
            t[pos][S[i]-'a']=tot;
        }
        cur=t[pos][S[i]-'a'];
        cout<<(last=num[cur])<<' ';
    }
    return 0;
}

有趣的性质

  • 对于插入一般我们都是在末尾插入,但是其实也可以同时进行从头插入

  • 因为可以发现整个字符串的不管是前后维护的回文子串是一样的,所以对于前/后缀都维护一下最长的回文子串所在的结点就可以了

posted @ 2022-06-05 13:00  Kzos_017  阅读(24)  评论(0编辑  收藏  举报