HDOJ - 3068 最长回文 Manacher
2013-04-26 21:03
141 查看
早就听说过这个方法..当时不理解就过了...今天再来写这题..带来的感觉很深刻...
充分利用前面判断过的内容...尽可能减少重复判断是Manacher的核心....
预处理..但凡回文串的问题..在这个串的最头和最末以及每个字符中间加入相同的冗余字符..这样就可以把奇偶情况一起讨论了..记住最后结果除以2...
dp [ i ] 代表以 s [ i ] 为中心的回文串最长长度...dp值从字符串最左更新到最右...每次除了更新dp [ i ] 还要维护两个值...w , i ( 前面一段某点为中心的回文所能到的最右的位置 w, 以及这个中间点是哪个 p )....
充分利用回文串的特点..左右对称相等.. 看下面两种情况:
1>
当前扫到了i...之前p能到最右距离w...那么可以将i对称p找到左侧的对应点...并且这个点的回文长度在p最长回为之内..那么dp[i]=dp[2*p-i]...直接赋值....
2>
当前点i对称于p的点是i'...而i'的最长回文范围已经超过p的范围...所以只能得出..以i为中点..w为右界的回文串是ok的...但要从w+1继续往后面判断..以i为中心找到不能回文为止..此时将p改为i...w改为i的最右位置....
关于效率的问题...由于w是单调往右移动的...所以时间效率是O(n)....
Program:
充分利用前面判断过的内容...尽可能减少重复判断是Manacher的核心....
预处理..但凡回文串的问题..在这个串的最头和最末以及每个字符中间加入相同的冗余字符..这样就可以把奇偶情况一起讨论了..记住最后结果除以2...
dp [ i ] 代表以 s [ i ] 为中心的回文串最长长度...dp值从字符串最左更新到最右...每次除了更新dp [ i ] 还要维护两个值...w , i ( 前面一段某点为中心的回文所能到的最右的位置 w, 以及这个中间点是哪个 p )....
充分利用回文串的特点..左右对称相等.. 看下面两种情况:
1>
当前扫到了i...之前p能到最右距离w...那么可以将i对称p找到左侧的对应点...并且这个点的回文长度在p最长回为之内..那么dp[i]=dp[2*p-i]...直接赋值....
2>
当前点i对称于p的点是i'...而i'的最长回文范围已经超过p的范围...所以只能得出..以i为中点..w为右界的回文串是ok的...但要从w+1继续往后面判断..以i为中心找到不能回文为止..此时将p改为i...w改为i的最右位置....
关于效率的问题...由于w是单调往右移动的...所以时间效率是O(n)....
Program:
#include<iostream> #include<string> #include<cmath> #include<algorithm> #include<map> #include<set> #include<queue> #define ll long long #define oo 1000000000 using namespace std; char str[250005],s[250005]; int dp[250005]; int main() { int l,i,j,w,p,k,ans; while (~scanf("%s",&str)) { l=strlen(str); memset(dp,0,sizeof(dp)); s[0]='*'; for (i=0;i<l;i++) s[i*2+1]=str[i],s[i*2+2]='*'; l*=2; memset(dp,0,sizeof(dp)); dp[0]=ans=1; w=p=0; for (i=1;i<=l;i++) { if (i<=w) dp[i]=dp[2*p-i]; if (i+dp[i]/2>=w) { p=i; if (w>=i) dp[i]=(w-i)*2; else w=i; dp[i]++; while (w+1<=l && s[w+1]==s[2*p-w-1]) dp[i]+=2,w++; } if (ans<dp[i]) ans=dp[i]; } printf("%d\n",ans/2); } return 0; }
相关文章推荐
- 【Manacher】 HDOJ 3068 最长回文
- HDOJ-3068 最长回文 (manacher求最长回文串)
- hdoj 3068最长回文【Manacher】
- Manacher HDOJ 3068 最长回文
- hdoj 3068 最长回文 【Manacher】
- hdoj 3068 最长回文 【manacher算法】
- 【HDOJ3068】最长回文(manacher)
- HDOJ3068 最长回文(Manacher)
- HDOJ 3068 最长回文(Manacher)
- hdoj3068--最长回文(manacher模板)
- hdoj 最长回文 3068 (字符串&manacher)
- HDU 3068 最长回文 (Manacher 模板题)
- hdu 3068 最长回文_Manacher模板
- 最长回文高效算法 HDOJ3068
- hdu 3068 最长回文 【Manacher求最长回文子串,模板题】
- HDU 3068 最长回文 Manacher
- hdu 3068 最长回文(manacher)
- hdu 3068 最长回文 (manacher模板)
- HDOJ 3068 最长回文
- 【HDOJ】【3068】最长回文