列舉子串的中心,往兩側擴充套件,將兩側對應位置的字元交替寫下來,得到乙個字串$s$。
若前後長度為$l$的子串迴圈同構,則在$s$中它們對應長度為$2l$的字首,需要滿足它可以由不超過$2$個偶回文串拼接而成。
有乙個結論是,若$s=uv$,其中$uv$都是偶回文串,那麼要麼$u$是$s$的最長偶回文字首,要麼$v$是$s$的最長偶回文字尾。
證明:設$s=x_1y_1=x_2y_2=x_3y_3$。
假設結論不成立,那麼顯然雙回文劃分數$\geq 3$,設$x_1$為$s$的最長回文字首,$y_3$是$s$的最長回文字尾,$x_2$和$y_2$都是回文串,則$y_1$和$x_3$都不是回文串。
因為$x_1$是最長回文字首,所以$|x_1|>|x_2|$,同理$|y_2|<|y_3|$,則$|x_1|>|x_2|>|x_3|$。
................[v.....]
[x1...................][y1....]
[x2..........][y2.............]
[x3.....][y3..................]
設$x_1=x_2v$,那麼因為$v$是回文串$y_2$的字首,所以$v^r$是$y_2$的字尾,也是$y_3$的字尾,因為$y_3$是回文串,所以$v$是$y_3$的字首,得出$x_3v$是$x_1$的字首。
因為$x_1$是回文串,$x_2$是$x_1$的字首,所以$x_2^r$是$x_1$的字尾,又因為$x_2$是回文串,所以$x_2$也是$x_1$的字尾,所以長度$|x_1|-|x_2|=|v|$是$x_1$的乙個週期,也是$x_1$的字首$x_3v$的乙個週期。這說明$|v|$也是$v^rx_3^r$的乙個週期,即$x_3^r$是$v^rv^r...v^rv^r$的字首。
因為$v$是回文串$x_1$的字尾,所以$v^r$是$x_1$的字首,而$|v|$是$x_1$的週期,所以$x_1$是$v^rv^r...v^rv^r$的字首,那麼$x_1$的字首$x_3$也是$v^rv^r...v^rv^r$的字首。
因為$x_3^r$和$x_3$都是$v^rv^r...v^rv^r$的字首,所以$x_3=x_3^r$,即$x_3$是回文串,和假設矛盾。所以結論成立。
通過manacher預處理出每個位置的最長回文半徑$f$,即可求出每個字首的最長偶回文字首和最長偶回文字尾,剩下部分可以根據$f$陣列$o(1)$判斷乙個子串是否是回文串。
時間複雜度$o(n^2)$。
#includeconst int n=10010;
int n,i,a[n],c[n],s[n],f[n],pre[n],suf[n],ans;
inline int min(int a,int b)
inline void umax(int&a,int b)
inline void solve(int x)
for(i=0;i<=m+1;i++)pre[i]=0,suf[i]=len;
for(i=3;i>1],i>>1);
} for(i=1;i<=m;i++)umax(pre[i],pre[i-1]);
for(i=m;i;i--)umin(suf[i],suf[i+1]);
for(i=0;i<=m;i++)if(suf[i]>=i)suf[i]=0;else suf[i]=(i-suf[i])<<1;
for(i=2;i<=m;i+=2)if(check(pre[i]+1,i)||check(1,i-suf[i]))ans++;
}int main()
字串 簡單 1544 整理字串
題目 給你乙個由大小寫英文本母組成的字串 s 乙個整理好的字串中,兩個相鄰字元 s i 和 s i 1 其中 0 i s.length 2 要滿足如下條件 若 s i 是小寫字元,則 s i 1 不可以是相同的大寫字元。若 s i 是大寫字元,則 s i 1 不可以是相同的小寫字元。請你將字串整理好...
字串的簡單操作
前段時間在csdn上面看到這樣乙個問題,樓主要求 將乙個字串中不同的字元新增到另外乙個字串中,最後還要進行排序操作 大致要求如下 string a a,b,c string b a,b,e,f 輸出結果為 abcdef 下面是我對這個的實現 static void main string args ...
字串的簡單操作
對於字串的處理,系統已經提供了很多的庫函式可供我們使用,比如strlen 計算字串的長度 strcpy 字串的拷貝 strcat 字串的鏈結 strcmp 字串的比較 strstr 字串的查詢 等等 很大程度上方便了我們的程式設計。下面列出一些例子來說明字串的處理 1 例如 在乙個字串中 hello...