回文子串的個數


# 題意

給定一個字符串,求字符串中有多少個回文子串
單獨一個字符也是一個回文串

# 題解
manacher,從1開始掃描整個回文半徑數組,以每個點為中心的
回文串的個數為 hw[i]/2,即除去分隔符的真實回文半徑
#1#2#3#3#2#1#

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=200010;
 4 char a[maxn],s[maxn<<1];
 5 int l[maxn<<1],r[maxn<<1];
 6 int n,hw[maxn],ans;
 7 // hw/2 即以 i 為中心的回文子串的個數
 8 // hw[ i ]-1即以 i 為中心的回文串的長度
 9 //在所有字符的前后 共插入n+1 個 '#'
10 inline void change() {
11     s[0]='~',s[1]='#';//邊界
12     for(int i=0; i<n; i++) {
13         s[i*2+2]=a[i];
14         s[i*2+3]='#';
15     }
16     n=n*2+2;
17     s[n]='@';// 設置邊界,兩個邊界不同
18 }
19 inline void manacher( ) {
20     int maxright=0 , mid;
21     for(int i = 1; i < n; i ++) {//枚舉1...2n-1
22         if(i < maxright)
23             hw[i] = min ( hw[(mid << 1) - i ]  , hw [mid] + mid - i );
24             // hw[(mid<<1)-i]即i關於mid對稱的點. hw[mid] +mid-i,為當前到最長回文串終點的距離,特判定對稱的點越界
25         else
26             hw[i] = 1;//hw[i]表示i點能夠擴展出的回文半徑
27         while( s[i + hw[i]] == s[i - hw[i]] )//s[]存儲字符串
28             ++ hw[i];
29         if(hw[i] + i > maxright) {
30             maxright = hw[i] + i - 1;
31             mid = i;
32         }
33     }
34 }
35 int main(){
36     cin>>a;
37     n=strlen(a);
38     change();
39     manacher();
40     int ans=0;
41     for(int i=0;i<n;i++)
42         ans+=hw[i]/2;
43     cout<<ans;
44 }

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM