关于Manacher

来源:互联网 发布:java表示一个数的次方 编辑:程序博客网 时间:2024/06/03 17:36

这好像是第一次写关于字符串的东西吧。[之前立的flag里好像有KMP AC自动机之类的] 跑题了
Manacher是今天新学得一个算法,感觉还是挺巧的。
给出一个问题:给定一个回文串,求它的最长回文子串长度

关于Manacher有一个比较巧的地方[其实这整个都挺巧的]:
对于判断一个数是否是回文串,需要分成该串长度为偶数和为奇数两种情况讨论,但如果我们对每个字符中都插入同一个特殊的字符,对计算的结果没有影响,而这两种情况也可以合并到一起计算了。
在字符串的开头也加入另一个特殊的字符作为分界情况的处理。

判断回文串也是一种判断匹配的方法。
所以Manacher算法和KMP一样,要尽可能利用已经匹配过的信息

算了不想打了
这个东西感觉网上有很多博客写的都挺好的,思想也不是很难理解
贴上模板好了
以HDU 3068为例
纯裸题,都没有写题解的必要了2333333

#include<cstdio>#include<cstring>#include<algorithm>#define ms(x,y) memset(x,y,sizeof(x))using namespace std;const int N = 110000+10;char s[N*2+10];int p[N*2+10];inline int Min(int a,int b){    return a<b?a:b;}int manacher(){    int len=strlen(s);    int mmax=-1;    for(int i=len;i>=0;i--){        s[i+i+2]=s[i];        s[i+i+1]='#';    }    s[0]='$';    int id=0,mx=0;    for(int i=1;i<=len<<1;i++){        if(i<mx) p[i] = Min(p[id*2-i],mx-i);        else p[i]=1;        while(s[i-p[i]]==s[i+p[i]]) p[i]++;        if(i+p[i]>mx){            id=i;            mx=p[i]+i;        }        if(p[i]>mmax) mmax=p[i];    }    return mmax-1;}void update(){    ms(p,0);}int main(){    while(scanf("%s",s)!=EOF){        int len=strlen(s);        update();        printf("%d\n",manacher());    }    return 0;}

代码的具体实现借鉴了网上的一些大神的,感觉还是挺巧的
【完了我现在养成了打完一句话就打个;的习惯,有毒233333】
【最近真的是很勤勉地在写博客啊qaq】

原创粉丝点击