【POJ 3974】 Palindrome
【题目链接】
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的更多相关文章
- 【POJ 3974】Palindrome
http://poj.org/problem?id=3974 Manacher模板题.Menci的博客讲得很好 有一点:Menci的代码中的right我感觉是代表能延伸到的最右端点的右边的点,因为r( ...
- 【POJ 1159】Palindrome
[POJ 1159]Palindrome 近期各种题各种奇葩思路已经司空见惯了...又新出个滚动数组= = 该题另一点须要知道 最少须要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 ...
- bzoj 2295: 【POJ Challenge】我爱你啊
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MB Description ftiasch是个十分受女生欢迎的同学,所以 ...
- 【链表】BZOJ 2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 382 Solved: 111[Submit][S ...
- BZOJ2288: 【POJ Challenge】生日礼物
2288: [POJ Challenge]生日礼物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 284 Solved: 82[Submit][St ...
- BZOJ2293: 【POJ Challenge】吉他英雄
2293: [POJ Challenge]吉他英雄 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 80 Solved: 59[Submit][Stat ...
- BZOJ2287: 【POJ Challenge】消失之物
2287: [POJ Challenge]消失之物 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 254 Solved: 140[Submit][S ...
- BZOJ2295: 【POJ Challenge】我爱你啊
2295: [POJ Challenge]我爱你啊 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 126 Solved: 90[Submit][Sta ...
- BZOJ2296: 【POJ Challenge】随机种子
2296: [POJ Challenge]随机种子 Time Limit: 1 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 114 Solv ...
随机推荐
- 01Hypertext Preprocessor
Hypertext Preprocessor PHP即Hypertext Preprocessor是一种被广泛使用的开放源代码多用途动态交互性站点的强有力的服务器端脚本语言尤其适用于 Web开发人员可 ...
- 洛谷——P3811 【模板】乘法逆元
P3811 [模板]乘法逆元 线性求逆元 逆元定义:若$a*x\equiv1 (\bmod {b})$,且$a$与$b$互质,那么我们就能定义: $x$为$a$的逆元,记为$a^{-1}$,所以我们也 ...
- [luogu4056 JSOI2009] 火星藏宝图 (贪心 dp)
传送门 Solution 一个显然的贪心:选的点数越多越好.这个随便推推就知道了. 那么我们就贪心的从一列上挑最靠下的转移 直接转移不斜率优化复杂度\(O(nm)\),吸一口O2过了... Code ...
- 集合:Iterator
why ? when ? how ? what ? 为什么需要集合呢? 在数据结构中链表.树.堆等一些操作都是由我们自己写的,这些操作是不是可以提取出来,以后要用就直接拿来用就好,这样非常方便. Ja ...
- MySQL4
MySQL数据库4 1 管理索引 创建索引帮助 help CREATE INDEX 创建索引 指令 CREATE INDEX 语法格式 CREATE INDEX index_name ON tbl_n ...
- python3爬虫-通过requests爬取西刺代理
import requests from fake_useragent import UserAgent from lxml import etree from urllib.parse import ...
- vue 刷新当前页面的时候重新调用新的cookie
data() { return{ AdminToken: this.getCookie('token'), } }, updated() { //刷新当前页面的时候重新调用新的cookie this. ...
- [luoguP2863] [USACO06JAN]牛的舞会The Cow Prom(Tarjan)
传送门 有向图,找点数大于1的强连通分量个数 ——代码 #include <stack> #include <cstdio> #include <cstring> ...
- 常州模拟赛d7t1 亲戚
分析:把题目换个方式理解,就是把各个点排成一列,并且指定了若干对的先后次序,问你有多少种序列满足要求. 显然是一道dp题,直接推出方程似乎有点点困难,那么先看看数据特点. 1.有一些点满足fi=0,那 ...
- POJ 1523 SPF 割点 Tarjan
SPF Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 9317 Accepted: 4218 Description C ...