初学manacher
来源:互联网 发布:java调dll内存泄露 编辑:程序博客网 时间:2024/05/18 16:15
求最长回文子串的有力工具。
按照一般的暴力判断方法,我们可以枚举每一个中点,然后从这个位置暴力向两边拓展。
但是实际上我们可以重复利用已经求得的信息,使期望复杂度接近O(n)。
我们设 rad[ i ] 表示以i为中心的回文串的长度的一半(向下取整),那么这个回文串的右端点就是 i+rad[i],左端点就是 i-rad[i]。
为了避免分类讨论回文串长度的奇数偶数的情况,我们在每两个点之间都插入一个相同的字符(这个字符不能在原字符串出现)。
然后我们维护一个p、maxpos,表示当前算出来的所有回文串的右端点最大的那个回文串的中点和右端点。
以下来自轩神的博客:
其中
红色:
橙色:
绿色:
①
此时
②
此时根据对称性也可以很显然地看出
由①②有,当
那么
③
这时即使
hdu3068
//Serene#include<algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>using namespace std;const int maxn=110000+10;char s[2*maxn];int rad[2*maxn],len,maxpos,p,ans;int main() {while(scanf("%s",s)!=EOF) {len=strlen(s);maxpos=0;ans=0;for(int i=len;i>=0;--i) {s[(i+1)<<1]=s[i];s[i<<1|1]='#';}s[0]='#';for(int i=2;i<=2*len&&maxpos!=2*len+1;++i) {if(maxpos>i) rad[i]=min(maxpos-i,rad[2*p-i]);else rad[i]=0;while(i-rad[i]>0&&i+rad[i]<=2*len+1&&s[i-rad[i]]==s[i+rad[i]]) rad[i]++;rad[i]--;if(i+rad[i]>maxpos) p=i,maxpos=i+rad[i];ans=max(ans,rad[i]);}printf("%d\n",ans);}return 0;}/*abababbbabbbaabbaababaa*/
阅读全文
0 0
- 初学manacher
- Manacher
- manacher
- Manacher
- Manacher
- manacher
- manacher
- manacher
- Manacher
- *Manacher
- Manacher
- 初学...
- 初学
- 初学
- 初学
- 初学
- 初学
- 初学
- hdu 1078
- HashMap中keySet()底层调用解析
- PHP基础数据类型之整型
- 两个输入框水平排列
- Python-Numpy(2)Array数组操作
- 初学manacher
- 文章标题
- Eclipse .java文件 颜色+几何形状的意义
- SVM入门(六)线性分类器的求解——问题的转化,直观角度
- curl请求https POST和GET方法
- HDU 2859
- 线段树模板
- android 利用cmdline,将参数从preloader传递到kernel
- QT 中实现HMAC-SHA1