Manacher 模板 【bzoj2565】 最长双回文子串
2017-02-25 21:11
239 查看
Manacher是一种可以获得一个串以每一个位置为中心最长回文半径的算法。
它的主要思想就是利用已知的信息来减少获得新信息的不必要操作。
已知的信息就是已经求出的回文串,比如这张图,我们已知黑色部分是一个回文串。
我们要求以红色中点位置为中心的回文串。
假设我们红色部分就是答案,那么在黑色回文串的左边一定有一个跟红色部分一模一样的串,并且红色中点的答案就等于蓝色中点的答案,这样我们就可以快速获得答案。
但是如果黑色的右端在所求位置的左侧或者红色部分的答案有可能超出黑色右端点,这个时候需要暴力匹配。
我们每次都利用右端点最大的已知子串,这样我们只会不断地扩展右端点,所以相当于把这个串从左到右扫一遍,时间复杂度O(n)。
模板代码:
题目大意:
求一个串的最长子串满足该子串可由两个回文串拼成。
题目分析:
插入分隔符,然后Manacher。
设置一个f数组,f[i]代表已第i个位置为结尾的回文串半径最长有多长。
这样可以通过枚举第二个串的回文中心,找到第一个串的结尾,再通过第一个串的结尾找到第一个串的回文中心,两个回文中心的距离恰好就是最长双回文子串的长度。
代码如下:
它的主要思想就是利用已知的信息来减少获得新信息的不必要操作。
已知的信息就是已经求出的回文串,比如这张图,我们已知黑色部分是一个回文串。
我们要求以红色中点位置为中心的回文串。
假设我们红色部分就是答案,那么在黑色回文串的左边一定有一个跟红色部分一模一样的串,并且红色中点的答案就等于蓝色中点的答案,这样我们就可以快速获得答案。
但是如果黑色的右端在所求位置的左侧或者红色部分的答案有可能超出黑色右端点,这个时候需要暴力匹配。
我们每次都利用右端点最大的已知子串,这样我们只会不断地扩展右端点,所以相当于把这个串从左到右扫一遍,时间复杂度O(n)。
模板代码:
int mx=0,mi=0; for(int i=1;i<=tot;i++) { if(mx>i) p[i]=Min(mx-i,p[2*mi-i]); else r[i]=1; while(a[i+p[i]]==a[i-p[i]]) p[i]++; if(i+p[i]>mx) mi=i,mx=i+p[i]; }
题目大意:
求一个串的最长子串满足该子串可由两个回文串拼成。
题目分析:
插入分隔符,然后Manacher。
设置一个f数组,f[i]代表已第i个位置为结尾的回文串半径最长有多长。
这样可以通过枚举第二个串的回文中心,找到第一个串的结尾,再通过第一个串的结尾找到第一个串的回文中心,两个回文中心的距离恰好就是最长双回文子串的长度。
代码如下:
#include<cstdio> #define N 120000 using namespace std; inline int Max(int x,int y) { return x>y?x:y; } inline int Min(int x,int y) { return x<y?x:y; } char s ; char a[N<<1]; int r[N<<1],tot; int f[N<<1],ans; int main() { scanf("%s",s); for(int i=0;s[i];i++) { a[++tot]='#'; a[++tot]=s[i]; } a[++tot]='#'; int mx=0,p=0; for(int i=1;i<=tot;i++) { if(mx>i) r[i]=Min(mx-i,r[2*p-i]); else r[i]=1; if(!f[i]) f[i]=i; while(a[i+r[i]]==a[i-r[i]]) { if(!f[i+r[i]]) f[i+r[i]]=i; r[i]++; } if(i+r[i]>mx) p=i,mx=i+r[i]; } for(int i=1;i<=tot;i++) ans=Max(ans,i-f[i-r[i]]); printf("%d\n",ans); return 0; }
相关文章推荐
- Girls' research(已完善的Manacher算法模板:输出最长回文子串)
- BZOJ2565 最长双回文串 【manacher】
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】
- BZOJ2565 最长双回文串 【manacher】
- Luogu-3805 (Manacher 最长回文子串)(模板)
- [bzoj2565]最长双回文子串
- 最长回文子串模板---Manacher算法。时间复杂度O(N)
- manacher求最长回文子串算法模板
- BZOJ 2565 双回文子串 Manacher 蜜汁贪心QQQ
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】
- {模板}Manacher最长回文子串
- Palindrome - POJ 3974 (最长回文子串,Manacher模板)
- bzoj2565 最长双回文子串
- 邝斌的ACM模板(Manacher 最长回文子串)
- 【模板】Manacher 算法 最长回文子串
- Manacher最长回文子串(模板)
- 【Manacher模板】HDU 3068——求最长回文子串
- 最大算法【Manacher模板】HDU 3068——求最长回文子串
- Manacher算法----最长回文子串
- BZOJ2565:最长双回文串(回文自动机)