國家集訓隊 最長雙回文串

2022-05-09 13:51:10 字數 1435 閱讀 7967

嘟嘟嘟

這道題,我的大致思想是先用manacher求出所有回文串,然後用剛好拼接在一起的兩個回文串的總長的最大值更新答案。

manacher是o(n)的,但是暴力的列舉回文中心能達到o(n2),所以得想辦法優化列舉。

令pre[i]表示離 i最遠且左半部分包含 i 的回文串的回文中心的位置,suf[i]表示離 i 最遠且右半部分包含 i 的回文串的回文中心的位置。有人會問,為什麼是包含,而不是到 i 結束的回文串?因為最優解對於這個回文串可能取不完,比如說abaab,單純看aba的話,只能取到ab + a = abaa,但實際上應該是a + baab = abaab。維護好這兩個陣列後,ans = max(suf[i] - pre[i])。

這兩個陣列的維護跟manacher有點像:對於pre,建乙個指標 j,然後掃維護好的回文半徑陣列,每一次把[j, i + p[i])的pre都更新成 i。suf的維護反過來即可。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include8 #include9 #include10 #include11

using

namespace

std;

12#define enter puts("")

13#define space putchar(' ')

14#define mem(a, x) memset(a, x, sizeof(a))

15#define rg register

16 typedef long

long

ll;17 typedef double

db;18

const

int inf = 0x3f3f3f3f;19

const db eps = 1e-8;20

const

int maxn = 1e5 + 5;21

inline ll read()

2226

while(isdigit(ch))

27if(last == '

-') ans = -ans;

28return

ans;29}

30 inline void

write(ll x)

3136

37int

n;38

char s[maxn], t[maxn << 1

];39

int p[maxn << 1

];40

41void

init()

4249

int pre[maxn << 2], suf[maxn << 2

];50

void

manacher()

5160}61

62int

main()

63

view code

國家集訓隊 最長雙回文串

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

國家集訓隊 最長雙回文串

題意是 求字串 a b c 且 c 在序列中 a 和 b 都是回文串 運用了回文字串優美的性質 刪掉任意兩個相同的字元仍然回文且長度減2 看到這題之後 我在想 如果把 a 字串的末尾 設為 a 的長度 b 字串的開始 設為 b 的長度 然後 設 a 字串的 右端點 代表的長度為 r i 設 b 字串...

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

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