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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

P4555 最长双回文串

發布時間:2023/12/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P4555 最长双回文串 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目描述

順序和逆序讀起來完全一樣的串叫做回文串。比如acbca是回文串,而abc不是(abc的順序為abc,逆序為cba,不相同)。

輸入長度為 n的串 S ,求 S的最長雙回文子串 T ,即可將 T 分為兩部分 XY,( ∣X∣,∣Y∣≥1|X|,|Y|≥1X,Y1 )且 XY 都是回文串。

輸入輸出格式

輸入格式:

一行由小寫英文字母組成的字符串 S

輸出格式:

一行一個整數,表示最長雙回文子串的長度。

輸入輸出樣例

輸入樣例#1:? baacaabbacabb 輸出樣例#1:? 12

說明

【樣例說明】

從第二個字符開始的字符串aacaabbacabb可分為aacaa與bbacabb兩部分,且兩者都是回文串。

對于100%的數據, 2≤∣S∣≤105

Solution:

  本題$zyys$啊!~

  很容易想到$manacher$,于是先打個板子看看,處理出以$i$為中心的最長回文半徑$p[i]$后,就斷思路了。

  我首先想到的是,在每次更新$p[i]$后,分別處理出以$i$為中心的半徑$p[i]$內,每個位置為開頭和結尾的最長回文子串長度($manacher$結束后直接枚舉斷點就可以得到答案),但是這樣強行又將復雜度拉到了$O(n^2)$。于是,開始斷線~

  后面看看巨佬們的思路,豁然**,我是真的蠢啊~

  其實,將我開始的思路修改一下即可:

  我們維護最長回文半徑$p[i]$的同時,再分別維護兩個東西,以$i$為結尾的最長回文子串的長度$ll[i]$,和以$i$為開頭的最長回文子串的長度$rr[i]$。

  那么很顯然,因為以$i$為中心的最長回文子串長度為$p[i]-1$,所以每次更新$p[i]$后,我們只需處理出當前這個回文子串的左右邊界(中間的每個點的$ll[i],rr[i]$可以在$manacher$結束后$O(n)$處理出),則$ll[i+p[i]-1]=max(ll[i+p[i]-1],p[i]-1)$(更新以$i+p[i]-1$為結尾的最長回文長度),同理$rr[i-p[i]+1]=max(rr[i-p[i]+1],p[i]-1)$。

  跑完$manacher$后,我們$O(n)$遞推出每個$#$為斷點的$ll[i]$和$rr[i]$,其中$rr[i]$因為是$i$結尾的回文長度,所以直接順推,每往后移一位,最長回文子串長度$-2$,于是$rr[i]=max(rr[i],rr[i-2]-2)$($i-2$是上一個$#$位置),同理$ll[i]$直接逆推,類似地$ll[i]=max(ll[i],ll[i+2]-2)$。

  最后枚舉每個$#$為斷點,更新$ans$就$OK$了。

代碼:

?

#include<bits/stdc++.h> #define For(i,a,b,c) for(int (i)=(a);(i)<=(b);(i)+=(c)) #define Bor(i,a,b,c) for(int (i)=(b);(i)>=(a);(i)-=(c)) #define Min(a,b) ((a)>(b)?(b):(a)) #define Max(a,b) ((a)>(b)?(a):(b)) using namespace std; const int N=200050; int p[N],ll[N],ans,rr[N],mx,id,cnt; char s[N],t[N]; int main(){scanf("%s",t);int len=strlen(t);s[++cnt]='$',s[++cnt]='#';For(i,0,len-1,1)s[++cnt]=t[i],s[++cnt]='#';s[++cnt]='\0';For(i,1,cnt,1){if(i<mx)p[i]=Min(p[id*2-i],mx-i);else p[i]=1;while(s[i-p[i]]==s[i+p[i]])p[i]++;if(mx<i+p[i])id=i,mx=i+p[i];ll[i+p[i]-1]=Max(ll[i+p[i]-1],p[i]-1);rr[i-p[i]+1]=Max(rr[i-p[i]+1],p[i]-1);}For(i,2,cnt,2)rr[i]=Max(rr[i],rr[i-2]-2);Bor(i,2,cnt,2)ll[i]=Max(ll[i],ll[i+2]-2);For(i,2,cnt,2)if(rr[i]&&ll[i])ans=Max(ans,ll[i]+rr[i]);cout<<ans;return 0; }

?

?

?

?

轉載于:https://www.cnblogs.com/five20/p/9090876.html

總結

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

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