manacher 模版

 1 // hw/2 即以 i 为中心的回文子串的个数
 2 // hw[ i ]-1即以 i 为中心的回文串的长度
 3 //在所有字符的前后 共插入n+1 个 '#'
 4 inline void change() {
 5     s[0]=s[1]='#';//插入后下标从1开始
 6     for(int i=0; i<n; i++) {
 7         s[i*2+2]=a[i];
 8         s[i*2+3]='#';
 9     }
10     n=n*2+2;// 即n*2+1,n上的字符值无意义
11     s[n]=0;
12 }
13 
14 inline void manacher( ) {
15     int maxright=0 , mid;
16     for(int i = 1; i < n; i ++) {//枚举1...2n-1
17         if(i < maxright)
18             hw[i] = min ( hw[(mid << 1) - i ]  , hw [mid] + mid - i );
19             // hw[(mid<<1)-i]即i关于mid对称的点. hw[mid] +mid-i,为外回文串的右边界到i的半径
20         else
21             hw[i] = 1;//hw[i]表示i点能够扩展出的回文半径
22         while( s[i + hw[i]] == s[i - hw[i]] )//s[]存储字符串
23             ++ hw[i];
24         if(hw[i] + i > maxright) {
25             maxright = hw[i] + i;
26             mid = i;
27         }
28     }
29 }

猜你喜欢

转载自www.cnblogs.com/hhyx/p/12528791.html