日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BZOJ2565 最长双回文子串 回文自动机,回文树

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2565 最长双回文子串 回文自动机,回文树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

bzoj2565: 最長雙回文串

題意

順序和逆序讀起來完全一樣的串叫做回文串。比如acbca是回文串,而abc不是(abc的順序為“abc”,逆序為“cba”,不相同)。
輸入長度為n的串S,求S的最長雙回文子串T,即可將T分為兩部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。 N<=100000。

?

這道題可以用manacher算法解決,但是用manacher解決問題的同時,有可能需要計算長度的關系,可能會出現混亂。在這里采用更清楚的回文自動機;

在做這道題之前需要掌握的知識是回文自動機的實現和作用,如果有不了解算法的同志,請自行翻大神博客進行學習:

https://www.cnblogs.com/crazyacking/p/5234823.html

在這里,由于是要找兩個回文串,還必須是相鄰的,所以我們可以通過把整串翻轉的方法實現求相鄰回文串,根據回文樹的作用,可以求出以下標i結尾的最長回文字符串,注意是以下標i結尾的最長串,而不是開始,不理解的話可以自己模擬一下字符加進回文自動機形成回文自動機的那些步驟,求出來之后可以枚舉相鄰的那個點來進行轉移,求出最長的雙回文串,這道題就結束了,現在上代碼:

?

1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cstring> 7 #include<string> 8 #include<queue> 9 using namespace std; 10 const int MAXN=100005; 11 int nxt[MAXN][26],fail[MAXN],len[MAXN],num[MAXN],cnt[MAXN],mx1[MAXN],mx2[MAXN]; 12 int n,m,k,l,r,last,p=0; 13 char s[MAXN],ops[MAXN]; 14 inline int getfail(int x) 15 { 16 while(s[n-len[x]-1]!=s[n]) x=fail[x]; 17 return x; 18 } 19 inline void add(int x,int i,int *mx) 20 { 21 last=getfail(last); 22 if(nxt[last][x]==0){ 23 len[++p]=len[last]+2; 24 fail[p]=nxt[getfail(fail[last])][x]; 25 nxt[last][x]=p; 26 num[p]=num[fail[p]]+1; 27 } 28 last=nxt[last][x]; 29 mx[i]=len[last]; 30 cnt[last]++; 31 return ; 32 } 33 int main() 34 { 35 scanf("%s",s+1); 36 m=strlen(s+1); 37 p=last=n=0; 38 len[++p]=-1; 39 fail[0]=p; 40 for(int i=1;i<=m;i++){ 41 n++; 42 add(s[i]-'a',i,mx1); 43 } 44 memset(fail,0,sizeof(fail)); 45 memset(cnt,0,sizeof(cnt)); 46 memset(num,0,sizeof(num)); 47 memset(len,0,sizeof(len)); 48 memset(nxt,0,sizeof(nxt)); 49 p=last=n=0;len[++p]=-1;fail[0]=p; 50 for(int i=1;i<=m;i++){ 51 ops[i]=s[m-i+1]; 52 } 53 for(int i=1;i<=m;i++){ 54 s[i]=ops[i]; 55 } 56 for(int i=1;i<=m;i++){ 57 n++; 58 add(s[i]-'a',i,mx2); 59 } 60 int ans=-1; 61 for(int i=1;i<=m;i++){ 62 ans=max(ans,mx1[i]+mx2[m-i+0]); 63 } 64 cout<<ans<<endl; 65 return 0; 66 }

?

轉載于:https://www.cnblogs.com/Alan-Luo/articles/9160813.html

總結

以上是生活随笔為你收集整理的BZOJ2565 最长双回文子串 回文自动机,回文树的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。