當前位置:
首頁 >
【回文自动机】bzoj3676 [Apio2014]回文串
發布時間:2025/7/14
22
豆豆
生活随笔
收集整理的這篇文章主要介紹了
【回文自动机】bzoj3676 [Apio2014]回文串
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
回文自動機講解!http://blog.csdn.net/u013368721/article/details/42100363
pam上每個點代表本質不同的回文子串。len(i)代表長度,cnt(i)代表個數(要最后在fail樹上dp一遍方可)。
答案直接枚舉一遍結點,然后用len(i)*cnt(i),取最大者即可。
回文自動機是非常優越的數據結構,可惜比manacher多一個字符集的空間……
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 300010 #define MAXC 26 struct PAM{int next[MAXN][MAXC];//next指針,next指針和字典樹類似,指向的串為當前串兩端加上同一個字符構成int fail[MAXN];//fail指針,失配后跳轉到fail指針指向的節點int cnt[MAXN];int num[MAXN];int len[MAXN];//len[i]表示節點i表示的回文串的長度int S[MAXN];//存放添加的字符int last;//指向上一個字符所在的節點,方便下一次addint n;//字符數組指針int p;//節點指針int newnode(int l){//新建節點for(int i=0;i<MAXC;++i){next[p][i]=0;}cnt[p]=0;num[p]=0;len[p]=l;return p++;}void init(){//初始化p=0;newnode(0);newnode(-1);last=n=0;S[n]=-1;//開頭放一個字符集中沒有的字符,減少特判fail[0]=1;}int get_fail(int x){//和KMP一樣,失配后找一個盡量最長的while (S[n-len[x]-1]!=S[n]){x=fail[x];}return x ;}void add(int c){c-='a';S[++n]=c;int cur=get_fail(last);//通過上一個回文串找這個回文串的匹配位置if (!next[cur][c]){//如果這個回文串沒有出現過,說明出現了一個新的本質不同的回文串int now=newnode(len[cur]+2);//新建節點fail[now]=next[get_fail(fail[cur])][c];//和AC自動機一樣建立fail指針,以便失配后跳轉 next[cur][c]=now;num[now]=num[fail[now]]+1;}last=next[cur][c];cnt[last]++;}void count(){//父親累加兒子的cnt,因為如果fail[v]=u,則u一定是v的子回文串!for(int i=p-1;i>=0;--i){cnt[fail[i]]+=cnt[i];}} }pam; typedef long long ll; char s[MAXN]; int main(){int len;pam.init();scanf("%s",s+1);len=strlen(s+1);for(int i=1;i<=len;++i){pam.add(s[i]);}pam.count();ll ans=0;for(int i=2;i<pam.p;++i){ans=max(ans,(ll)pam.cnt[i]*pam.len[i]);}printf("%lld\n",ans);return 0; }轉載于:https://www.cnblogs.com/autsky-jadek/p/6935356.html
總結
以上是生活随笔為你收集整理的【回文自动机】bzoj3676 [Apio2014]回文串的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: drawable自定义字体颜色
- 下一篇: 快速优雅的为React组件生成文档