| 
 | 
	
 
 本帖最后由 低沉的游鱼 于 2014-6-17 22:26 编辑  
 
已被APIO题完虐,8分滚粗了。。于是我要下定决心好好学习。首先就学了一下manacher算法,T1要用到的算法 
 
比如一个字符串abacaba,要求出里面所有的回文串。 如果回文串长度是奇数,就直接从中心向两边展开就行了。但如果是偶数呢?我们需要一个对这个字符串稍作变形。将这个字符串变为#a#b#a#c#a#b#a#。(#是一个辅助字符,要保证它在原串里不出现)。这样一来,原来长度是奇数的回文串长度还是奇数,长度为偶数的回文串就变成从其中一个#号展开。我们用p表示在这个新的字符串str中,以str为中心的最长回文串半径。这样一来,p-1表示的以str为中心的回文串在原串中的长度(很好证明,这里不多说)。 
 
先贴一个完整的代码 
- #include<iostream>  
 
 - #include<cstring>  
 
 - using namespace std;  
 
 -   
 
 - int manacher (char* s, int len)  
 
 - {  
 
 -     int nlen = 2 * len + 3;  
 
 -     char* str = new char[nlen];      
 
 -     int i = 0; 
 
 -     int max = 0;  
 
 -     str[0] = ' ~';
 
 -     str[1] = '#';  
 
 -     for (; i < len; i++)  
 
 -     {  
 
 -         str[i * 2 + 2] = s[i];  
 
 -         str[i * 2 + 3] = '#';  
 
 -     }  
 
 -     str[nlen - 1] = 0;  
 
 -     int* p = new int[nlen];  
 
 -   
 
 -     for (int i = 1; i < nlen; i++)  
 
 -     {  
 
 -         p[i] = 0;  
 
 -     }  
 
 -   
 
 -     int id = 0;  
 
 -     for (i = 1; i < nlen; i++)  
 
 -     {  
 
 -         if (max > i)  
 
 -             p[i] = min(p[2*id-i], max-i);  
 
 -         else  
 
 -             p[i] = 1;  
 
 -         while (str[i+p[i]] == str[i-p[i]])  
 
 -             p[i]++;  
 
 -         if (p[i]+i > max)  
 
 -         {  
 
 -             max = p[i] + i;  
 
 -             id = i;  
 
 -         }  
 
 -     }  
 
 -   
 
 -     int mx = 0;  
 
 -     for (i = 1; i < nlen; i++)  
 
 -     {  
 
 -         if (mx < p[i] - 1)  
 
 -             mx = p[i] - 1;  
 
 -     }  
 
 -     return mx;  
 
 - }  
 
 -   
 
 - int main()  
 
 - {  
 
 -     char ch[100];  
 
 -     while (cin >> ch)  
 
 -     {  
 
 -         cout << manacher(ch, strlen(ch)) << endl;  
 
 -     }  
 
 -     return 0;  
 
 - }  
 
  复制代码 
 
 
这一句 
 
 if (max > i)   
            p = min(p[2*id-i], max-i);   
 
是整个算法中很重要的一个环节,利用了回文串的对称性,避免了许多不必要的计算。max表示的是之前的回文串匹配到的最远的位置,id保存的是这个回文串的i值。p[2*id-i]表示的就是i关于id对称的j的位置。但如果j的回文串长度较长,对称过来以后超出max的话,超出部分是还没有匹配的。因此,应该取的是两者之间较小值。 
 
下图可能有助于理解 
  |   
 
 
 
 |