P5496 【模板】回文自动机(PAM)

P5496 【模板】回文自动机(PAM)

题意

给定一个字符串(s),问以每个位置结尾的回文串有多少个,询问在线。

(|s|le 5cdot 10^5)

分析

回文自动机上每个回文串的答案等于其最长回文后缀的答案+1。

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=5e5+10;
char s[maxn];
int n,now;
struct PAM{
    int son[maxn][26],fail[maxn],len[maxn],num[maxn],tot,last;
    int newnode(int x){
        ++tot;
        for(int i=0;i<26;i++) son[tot][i]=0;
        num[tot]=fail[tot]=0;len[tot]=x;
        return tot;
    }
    void init(){
        tot=-1;newnode(0);newnode(-1);
        fail[0]=1;
        last=0;
    }
    int gao(int x){
        while(s[now-len[x]-1]!=s[now]) x=fail[x];
        return x;
    }
    void insert(){
        int p=gao(last);
        if(!son[p][s[now]-'a']){
            int tmp=son[gao(fail[p])][s[now]-'a'];
            son[p][s[now]-'a']=newnode(len[p]+2);
            fail[tot]=tmp;
            num[tot]=num[fail[tot]]+1;
        }
        last=son[p][s[now]-'a'];
    }
    int qy(){
        return num[last];
    }
}P;
int main(){
    //ios::sync_with_stdio(false);
    //freopen("in","r",stdin);
    scanf("%s",s+1);
    n=strlen(s+1);
    P.init();
    int res=0;
    for(now=1;now<=n;now++){
        s[now]=(s[now]-'a'+res)%26+'a';
        P.insert();
        printf("%d ",res=P.qy());
    }
    return 0;
}
原文地址:https://www.cnblogs.com/xyq0220/p/13937118.html