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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

發(fā)布時(shí)間:2025/3/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ2565 最长双回文子串 回文自动机,回文树 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

bzoj2565: 最長(zhǎng)雙回文串

題意

順序和逆序讀起來(lái)完全一樣的串叫做回文串。比如acbca是回文串,而abc不是(abc的順序?yàn)椤癮bc”,逆序?yàn)椤癱ba”,不相同)。
輸入長(zhǎng)度為n的串S,求S的最長(zhǎng)雙回文子串T,即可將T分為兩部分X,Y,(|X|,|Y|≥1)且X和Y都是回文串。 N<=100000。

?

這道題可以用manacher算法解決,但是用manacher解決問(wèn)題的同時(shí),有可能需要計(jì)算長(zhǎng)度的關(guān)系,可能會(huì)出現(xiàn)混亂。在這里采用更清楚的回文自動(dòng)機(jī);

在做這道題之前需要掌握的知識(shí)是回文自動(dòng)機(jī)的實(shí)現(xiàn)和作用,如果有不了解算法的同志,請(qǐng)自行翻大神博客進(jìn)行學(xué)習(xí):

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

在這里,由于是要找兩個(gè)回文串,還必須是相鄰的,所以我們可以通過(guò)把整串翻轉(zhuǎn)的方法實(shí)現(xiàn)求相鄰回文串,根據(jù)回文樹(shù)的作用,可以求出以下標(biāo)i結(jié)尾的最長(zhǎng)回文字符串,注意是以下標(biāo)i結(jié)尾的最長(zhǎng)串,而不是開(kāi)始,不理解的話可以自己模擬一下字符加進(jìn)回文自動(dòng)機(jī)形成回文自動(dòng)機(jī)的那些步驟,求出來(lái)之后可以枚舉相鄰的那個(gè)點(diǎn)來(lái)進(jìn)行轉(zhuǎn)移,求出最長(zhǎng)的雙回文串,這道題就結(jié)束了,現(xiàn)在上代碼:

?

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 }

?

轉(zhuǎn)載于:https://www.cnblogs.com/Alan-Luo/articles/9160813.html

總結(jié)

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

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。