JSOI2016 扭動的回文串

2022-09-19 23:09:10 字數 856 閱讀 8198

清新結論配上巨大碼量的雜湊解法

第一種情況和第二種情況很容易解決,可以直接求乙個正向雜湊值在求乙個反轉後的雜湊值,然後列舉回文中心,二分擴充套件了多少即可。

思考扭動的回文串應該滿足那些特性,首先,一定是一段滿足情況 \(1\) 或情況 \(2\) 的子串 \(s\),然後左邊新增了一些,右邊新增了一些,很明顯,無論 \(s\) 是 \(a\) 的子串還是 \(b\) 的,左側新增的都在 \(a\) 中,右側的都在 \(b\) 中。

那麼自然想到列舉所以滿足條件的,但可惜的是,滿足條件的 \(s\) 的個數是 \(n^2\) 級別的。

由於無論如何都無法在查詢上進行優化,因為壓根不可能全找出來,考慮觀察一些性質,不妨假設 \(s\) 是以 \(l\) 為開始,\(r\) 為結尾,可以向兩側擴充套件的最長長度為 \(l\) ,若 \(k\) 為最大的滿足 \(l\gets l-k\),\(r\gets r+k\) 為回文串的非負整數,則依然可以向兩側擴充套件 \(l-k\) 的長度,這個是顯然的,所以對於乙個確定的中心,當回文半徑增長時,總長度不降,所以只需要檢查以 \(i\) 為回文中心的最長回文串即可,當然這個結論其實還有很多其他的理解方式,比如:當半徑增長時,其實是放寬了對向兩側擴充套件的那段字串的限制,也可以解釋這個總長度不減的結論。

實現就是找到以 \(i\) 為中心的最長的那個回文串,向兩側嘗試擴充套件,然後打擂台比下長度,需要注意回文中心並不確認在那個字串內,還可能是夾在兩個字元中間,分討即可。

乙個簡化分討的技巧,解決回文中心在 \(b\) 串內其實就是相當於把 \(a\) 串和 \(b\) 串都反轉再交換,然後跑中心在 \(a\) 中的**。

兩份**思路上沒區別,只不過第乙份沒有經過任何簡化。

code1 3.60kb

code2 2.20kb

JSOI2016 扭動的回文串

description jyy有兩個長度均為n的字串a和b。乙個 扭動字串s i,j,k 由a中的第i個字元到第j個字元組成的子串 與b中的第j個字元到第k個字元組成的子串拼接而成。比如,若a xyz b uvw 則扭動字串s 1,2,3 xyvw jyy定義乙個 扭動的回文串 為如下情況中的乙個 ...

JSOI2016 扭動的回文串

可以發現最後的答案一定長成 a 串和 b 串的一對對稱的子串 長度可以為 0 然後中間夾著 a 串或者 b 串中的乙個回文串 長度可以為 0 對於每乙個中心點,對應的最大的答案中間所夾的那個回文串一定是以這個中心點為對稱中心的最長回文串 那麼就從以這個中心點為對稱中心的最長回文串的兩邊開始找那個 a...

JSOI 2016 扭動的字串

給出兩個長度為 n 的字串 a,b s i,j,k 表示把 a 中的 i,j 和 b 中的 j,k 拼接起來的字串 問所有回文的 s i,j,k 或者 a,b 中的回文子串的最長長度 列舉回文串的中心。可以發現,如果能在當前字串內擴充套件就盡量擴充套件,不能擴充套件了再嘗試和另乙個字串匹配。對於前者...