#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
const int mod=19930726;
struct node{
int len,fail,ch[26],siz;
friend bool operator <(node a,node b) {
return a.len>b.len;
}
}prt[N];
int n,num,len,lst;
char s[N];
int getfail(int x) {
while(s[n-prt[x].len-1]!=s[n]) x=prt[x].fail;
return x;
}
void extand(int x) {
int cur=getfail(lst); //时间复杂度分析:O(n)
int now=prt[cur].ch[x];
if(!now) {
now=++num;
prt[now].len=prt[cur].len+2;
prt[now].fail=prt[getfail(prt[cur].fail)].ch[x]; //由于外层是O(n),而内层跳fail,外层也会减小,所以可以看作外层的从动点,是比外层循环小的
prt[cur].ch[x]=now; //这一句要写在上一句后面,因为要保证 ch[x]=0 ,此时cur=-1
}
prt[now].siz++;
lst=now;
}
void calc() {
for(int i=num;i>=2;i--) //长的字符串一定包括短的字符串
prt[prt[i].fail].siz+=prt[i].siz;
}
int main() {
// 关于优先级的问题:0是空串,1的长度是-1,所以0的优先级比1高
num=lst=1,prt[1].len=-1,prt[0].fail=prt[1].fail=1;
scanf("%d",&len);
scanf("%s",s+1);
for(n=1;n<=len;n++) extand(s[n]-'a');
calc();
}
【模板】回文自动机
最新推荐文章于 2023-04-22 19:00:09 发布