【题目链接】

http://poj.org/problem?id=3974

【算法】

解法1 :

字符串哈希

我们可以分别考虑奇回文子串和偶回文子串,从前往后扫描字符串,然后二分答案,检验可以用哈希

时间复杂度 : O(TNlog(N))

解法2

Manacher算法

这个算法可以在O(n)时间内求出最长回文子串,读者可以自行查阅资料,笔者不进行详细的介绍

两种方法的效率比对

           显然,Manacher算法的复杂度是优于字符串哈希的,笔者的两份代码在POJ上的运行时间分别为4891MS和266MS

【代码】

代码1

/*
Algorithm : Hash
Time Complexity : O(Tnlog(n))
*/ #include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXL 1000010
typedef unsigned long long ULL;
const int P = ; int i,len,l,r,mid,tmp,ans,TC;
ULL f[MAXL],ha[MAXL],hb[MAXL];
char s[MAXL]; inline ULL getha(int l,int r)
{
return ha[r] - ha[l-] * f[r-l+];
}
inline ULL gethb(int l,int r)
{
int tmp = l;
l = len - r + ;
r = len - tmp + ;
return hb[r] - hb[l-] * f[r-l+];
} int main()
{ f[] = ;
for (i = ; i < MAXL; i++) f[i] = f[i-] * P;
while (scanf("%s",s+))
{
len = strlen(s+);
if (s[] == 'E') break;
for (i = ; i <= len; i++) ha[i] = ha[i-] * P + (s[i] - 'a' + );
reverse(s+,s+len+);
for (i = ; i <= len; i++) hb[i] = hb[i-] * P + (s[i] - 'a' + );
ans = ;
for (i = ; i <= len; i++)
{
l = ; r = min(i-,len-i);
tmp = ;
while (l <= r)
{
mid = (l + r) >> ;
if (getha(i-mid,i) == gethb(i,i+mid))
{
tmp = mid;
l = mid + ;
} else r = mid - ;
}
ans = max(ans,*tmp+);
l = ; r = min(i,len-i);
tmp = ;
while (l <= r)
{
mid = (l + r) >> ;
if (getha(i-mid+,i) == gethb(i+,i+mid))
{
tmp = mid;
l = mid + ;
} else r = mid - ;
}
ans = max(ans,*tmp);
}
printf("Case %d: %d\n",++TC,ans);
} return ; }

代码2

/*
Algorithm : Manacher
Time Complexity : O(TN)
*/ #include <algorithm>
#include <bitset>
#include <cctype>
#include <cerrno>
#include <clocale>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <limits>
#include <list>
#include <map>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <utility>
#include <vector>
#include <cwchar>
#include <cwctype>
#include <stack>
#include <limits.h>
using namespace std;
#define MAXN 1000010 int TC;
char s[MAXN<<]; inline void Manacher()
{
int i,len,mx = ,pos = ,ans = ;
static char tmp[MAXN<<];
static int p[MAXN<<];
len = strlen(s+);
for (i = ; i <= len; i++)
{
tmp[*i-] = '#';
tmp[*i] = s[i];
}
tmp[len = * len + ] = '#';
for (i = ; i <= len; i++)
{
if (mx > i) p[i] = min(p[*pos-i],mx-i);
else p[i] = ;
while (i - p[i] >= && i + p[i] <= len && tmp[i-p[i]] == tmp[i+p[i]]) p[i]++;
if (i + p[i] - > mx)
{
mx = i + p[i] - ;
pos = i;
}
}
for (i = ; i <= len; i++) ans = max(ans,p[i]-);
printf("Case %d: %d\n",++TC,ans);
} int main()
{ while (scanf("%s",s+) != EOF)
{
if (s[] == 'E') break;
Manacher();
} return ; }

【POJ 3974】 Palindrome的更多相关文章

  1. 【POJ 3974】Palindrome

    http://poj.org/problem?id=3974 Manacher模板题.Menci的博客讲得很好 有一点:Menci的代码中的right我感觉是代表能延伸到的最右端点的右边的点,因为r( ...

  2. 【POJ 1159】Palindrome

    [POJ 1159]Palindrome 近期各种题各种奇葩思路已经司空见惯了...又新出个滚动数组= = 该题另一点须要知道 最少须要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 ...

  3. bzoj 2295: 【POJ Challenge】我爱你啊

    2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec  Memory Limit: 128 MB Description ftiasch是个十分受女生欢迎的同学,所以 ...

  4. 【链表】BZOJ 2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 382  Solved: 111[Submit][S ...

  5. BZOJ2288: 【POJ Challenge】生日礼物

    2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 284  Solved: 82[Submit][St ...

  6. BZOJ2293: 【POJ Challenge】吉他英雄

    2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 80  Solved: 59[Submit][Stat ...

  7. BZOJ2287: 【POJ Challenge】消失之物

    2287: [POJ Challenge]消失之物 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 254  Solved: 140[Submit][S ...

  8. BZOJ2295: 【POJ Challenge】我爱你啊

    2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 126  Solved: 90[Submit][Sta ...

  9. BZOJ2296: 【POJ Challenge】随机种子

    2296: [POJ Challenge]随机种子 Time Limit: 1 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 114  Solv ...

随机推荐

  1. string 字符串--------redis

    APPEND 语法:APPEND KEY VALUE 如果key已经存在并且是一个字符串,append 命令将value追加到key原来的值的末尾. 如果key不存在,append就简单地将给定key ...

  2. 网络编程 - 简单的socket例子

    1.客户端 #客户端import socketclient=socket.socket() #生成socket连接对象client.connect(("localhost",696 ...

  3. 在PL/SQL DEV里面有把锁一样的按钮,点击它会跳出“these query result are not updateable,include the ROWID to get updateab

    在PL/SQL DEV里面有把锁一样的按钮,点击它会跳出“these query result are not updateable,include the ROWID to get updateab ...

  4. [luogu4127 AHOI2009] 同类分布 (数位dp)

    传送门 Solution 裸数位dp,空间存不下只能枚举数字具体是什么 注意memset最好为-1,不要是0,有很多状态答案为0 Code //By Menteur_Hxy #include < ...

  5. document.documentElement

    1,释意document.documentElement 属性可返回文档的根节点.2,兼容在IE怪异模式下(IE8及以下)无法获取到 HTML标签,用document.body代替: 其余兼容问题参考 ...

  6. accept阻塞

    一直以来以为accept阻塞的时候,若另有线程关闭相应的监听套接字,accept会立即返回. 今天先是在NDK上试,没反应.又在ARCHLINUX试了下,还是没反应.难道是我一直记的都是错的!!!!! ...

  7. 被 idea 坑了的记录篇

    这个星期真的是波折的一周~~~~ 不得不吐槽下无敌坑的自己了,社会我娜姐,坑起来连自己都坑~~ 其实这也不全算我自己的坑,我只是卸载了idea,重新装了一下而已,很神奇的把idea的几个坑全撞了一遍( ...

  8. JavaSE 学习笔记之新特性之泛型(二十)

    泛型:jdk1.5版本以后出现的一个安全机制.表现格式:< > 好处: 1:将运行时期的问题ClassCastException问题转换成了编译失败,体现在编译时期,程序员就可以解决问题. ...

  9. [luoguP1196] 银河英雄传说(并查集)

    传送门 记录 up[x] 表示 x 上方有多少个 all[x] 表示当前连通的有多少个 find 的时候 和 合并的时候 更新一下即可 ——代码 #include <cstdio> #in ...

  10. reids桌面管理工具:RedisDesktopManager下载、使用

    概要:一款好用的Redis桌面管理工具,支持命令控制台操作,以及常用,查询key,rename,delete等操作. 下载软件,请点击下面链接,进入下载页,选择对应版本: https://redisd ...