國家集訓隊 最長雙回文串

2022-05-05 11:57:07 字數 1379 閱讀 6567

題意是 求字串 a +b = c 且 c 在序列中 a 和 b 都是回文串

運用了回文字串優美的性質:刪掉任意兩個相同的字元仍然回文且長度減2

看到這題之後 我在想 如果把 a 字串的末尾 設為 a 的長度 b 字串的開始 設為 b 的長度

然後 設 a 字串的 右端點 代表的長度為 \(r_i\)

設 b 字串的 左端點 代表的長度為 \(l_i\)

然後 求 \(max\)

\(\)

但是你會發現這樣是不會得到最優解的 就像這樣

aaaaa
答案是5 但是你只更新了 \(l_5\) 和 \(r_1\) 的值 所以程式認為的答案不是5 是 0

這樣你就要開始遞推

其實你統計的資訊都是在分隔符上…然後你會發現兩個分隔符裡有乙個字元

所以你 遞推式 是 \(l_i\) =max - 2\)} \(r_i\) = max-2\)}

然後再取 \(max\)

\(\)

#includeusing namespace std ;

#define int long long

#define fi first

#define se second

#define pb emplace_back

inline int read()

template < typename t > inline bool cmax(t & x , t y)

template < typename t > inline bool cmin(t & x , t y)

inline int qp(int x , int y , int mod)

const int n = 2e5 + 10 ;

char s[n] , fix[n << 1] ;

int p[n << 1] ;

int l[n << 1] , r[n << 1] ;

signed main() int ans = 0 ;

for(register int i = 2 ; i <= len ; i += 2) cmax(r[i] , r[i - 2] - 2) ;

for(register int i = len ; i >= 1 ; i -= 2) cmax(l[i] , l[i + 2] - 2) ;

int qwq = 2333 ;

for(register int i = 1 ; i <= len ; i ++) (l[i] && r[i]) ? cmax(ans , l[i] + r[i]) : qwq;

printf("%lld\n" , ans) ;

return 0 ;

}

國家集訓隊 最長雙回文串

可能還是非常板子的 manacher 還是先跑一遍 manacher 處理出來所有的回文半徑 r i 由於我們要找的答案是兩個回文串拼了起來,所以我們考慮列舉中間這個拼接處 所以我們要找到每乙個 i 其左邊能夠到達 i 的和右邊能到達 i 的最大的回文半徑 顯然並不能直接使用 i r i 和 i r...

國家集訓隊 最長雙回文串

嘟嘟嘟 這道題,我的大致思想是先用manacher求出所有回文串,然後用剛好拼接在一起的兩個回文串的總長的最大值更新答案。manacher是o n 的,但是暴力的列舉回文中心能達到o n2 所以得想辦法優化列舉。令pre i 表示離 i最遠且左半部分包含 i 的回文串的回文中心的位置,suf i 表...

國家集訓隊 最長雙回文串 馬拉車

傳送門 輸入長度為n的串s,求s的最長雙回文子串t,即t可分為兩部分x和y且x和y都是回文串。考慮列舉中間的斷點,所以我們只要記錄以i為開頭的最長回文串和以i為結尾的最長回文串。通過中心和長度求開頭已經在 這篇 裡面講過了,這裡不再贅述。結尾也只需自己慢漫推一推也可出來。可是以某個位置為開頭的最長回...