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;
}