1. 程式人生 > >【APIO2014】—迴文串(迴文自動機)

【APIO2014】—迴文串(迴文自動機)

傳送門

迴文自動機簡單題

因為不想學字尾自動機做法,於是去大概把迴文自動機學了

感覺比字尾自動機簡單多了啊

很顯然就是 f a i l fail 樹上 m

a x ( s i z [ u ] l
e n [ u ] ) max(siz[u]*len[u])

然後…就完了啊

#include<bits/stdc++.h>
using
namespace std; #define ll long long inline int read(){ char ch=getchar(); int res=0; while(!isdigit(ch))ch=getchar(); while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar(); return res; } const int N=300005; char a[N]; struct pam{ int ch[27],fail,len,cnt; }p[N]; int n,tot,last; ll ans; int main(){ scanf("%s",a+1); n=strlen(a+1),a[0]='#'; p[0].fail=1,p[1].len=-1,++tot; for(int i=1;i<=n;i++){ while(a[i-p[last].len-1]!=a[i])last=p[last].fail; if(!p[last].ch[a[i]-'a']){ p[++tot].len=p[last].len+2; int j=p[last].fail; while(a[i-p[j].len-1]!=a[i])j=p[j].fail; p[tot].fail=p[j].ch[a[i]-'a']; p[last].ch[a[i]-'a']=tot; } last=p[last].ch[a[i]-'a']; p[last].cnt++; } for(int i=tot;i>=2;i--){ p[p[i].fail].cnt+=p[i].cnt; if((ll)p[i].cnt*p[i].len>ans)ans=(ll)p[i].cnt*p[i].len; } cout<<ans; }