洛谷 P4287 雙倍回文 Manacher

2021-09-25 21:04:37 字數 1084 閱讀 9217

manacher演算法用的還是不夠熟悉啊,被卡了好久。。。一會再寫個回文自動機的做法吧

清晰的回文自動機寫法

題意:若乙個回文串左半部分和有半部分分別為乙個回文串,則這個回文串被稱為雙倍回文串(這名字有點傻呀!)。求:給定乙個回文串,問最長的雙倍回文串有多長。

思路:由於雙倍回文串是建立在回文串的基礎上的,因此我們只需要對回文串動動手腳就行了

思考:若在manacher演算法處理好字串後再對回文串進行判定,由於演算法得到的p陣列是當前位置能向兩邊拓展的最長回文串,因此為了遍歷所有的回文串,必須將每個位置的p向下列舉;但這樣勢必造成一些重複列舉(其實不重要),比如當前回文串被包含在乙個更長的回文串,且在其右半部分,則顯然左半部分已經列舉過跟當前回文串一樣的回文串的p

為了捨棄這樣的重複的列舉,我們採取在構建p陣列的過程中進行雙倍回文串的判定

顯然,只有在演算法中i+p[i]>r即當前回文串右側突破的最遠右邊界,當前回文串才不是被列舉過的,也就是說它需要被判定一下是否為雙倍回文串。這樣,演算法複雜度就達到了o(n)

最後是判定過程,建議在草稿紙上隨便畫畫,然後細節就明了了

//#pragma comment(linker, "/stack:102400000,102400000")

#include "bits/stdc++.h"

#define pb push_back

#define ls l,m,now<<1

#define rs m+1,r,now<<1|1

#define hhh printf("hhh\n")

#define see(x) (cerr<<(#x)<<'='<<(x)inline int read()

const int maxn = 1e6+10;

const int mod = 1e9+7;

const double eps = 1e-9;

char s[maxn], s0[maxn];

int p[maxn];

int change()

}if(r}

return ans;

}int main()

洛谷 4287 雙倍回文

記字串ww的倒置為w rwr。例如 abcd r dcba abcd r dcba,abba r abba abba r abba。對字串x,如果xx滿足x r xxr x,則稱之為回文 例如abba是乙個回文,而abed不是。如果x能夠寫成的ww rww rwwrwwr形式,則稱它是乙個 雙倍回文...

洛谷P1802 5倍經驗日

現在樂鬥有活動了!每打乙個人可以獲得5倍經驗!absi2011卻無奈的看著那一些比他等級高的好友,想著能否把他們乾掉。乾掉能拿不少經驗的。現在absi2011拿出了x個迷你裝藥物 嗑藥打人可恥 準備開始與那些人打了 由於迷你裝乙個只能管一次,所以absi2011要謹慎的使用這些藥,悲劇的是,沒到達最...

洛谷 P1802 5倍經驗日

現在樂鬥有活動了!每打乙個人可以獲得5倍經驗!absi2011卻無奈的看著那一些比他等級高的好友,想著能否把他們乾掉。乾掉能拿不少經驗的。現在absi2011拿出了x個迷你裝藥物 嗑藥打人可恥 準備開始與那些人打了 由於迷你裝乙個只能管一次,所以absi2011要謹慎的使用這些藥,悲劇的是,沒到達最...