题目链接:http://poj.org/problem?id=3974

Time Limit: 15000MS Memory Limit: 65536K

Description

Andy the smart computer science student was attending an algorithms class when the professor asked the students a simple question, "Can you propose an efficient algorithm to find the length of the largest palindrome in a string?"

A string is said to be a palindrome if it reads the same both forwards and backwards, for example "madam" is a palindrome while "acm" is not.

The students recognized that this is a classical problem but couldn't come up with a solution better than iterating over all substrings and checking whether they are palindrome or not, obviously this algorithm is not efficient at all, after a while Andy raised his hand and said "Okay, I've a better algorithm" and before he starts to explain his idea he stopped for a moment and then said "Well, I've an even better algorithm!".

If you think you know Andy's final solution then prove it! Given a string of at most 1000000 characters find and print the length of the largest palindrome inside this string.

Input

Your program will be tested on at most 30 test cases, each test case is given as a string of at most 1000000 lowercase characters on a line by itself. The input is terminated by a line that starts with the string "END" (quotes for clarity). 

Output

For each test case in the input print the test case number and the length of the largest palindrome. 

Sample Input

abcbabcbabcba
abacacbaaaab
END

Sample Output

Case 1: 13
Case 2: 6

题意:

给出若干个字符串,求最长回文子串的长度。

题解:

首先预处理字符串的长度为 $i$ 的前缀子串的哈希值 $pre[i]$,

再把字符串反转,预处理新的字符串的长度为 $i$ 的前缀子串的哈希值 $suf[i]$,

这样,如果在原串中存在一个 $[l_1,r_1]$ 的回文串,那么对应到新串,这个区间就是 $[l_2,r_2] = [len - r_1 +1,len - l_1 + 1]$,这两个子串的哈希值应当是相等的,即:

$pre[r_1 ] - pre[l_1 - 1] \times P^x = suf[r_2 ] - suf[l_2 - 1] \times P^x$

其中,$x = r_1 - l_1 + 1 = r_2 - l_2 +1$。

所以,不难想到,我们如果二分回文子串的长度,就可以 $O\left( {\left| S \right|\log \left| S \right|} \right)$ 求出最长回文子串。

但是,这样做的话,在测样例时就会发现问题,奇数长度的回文子串和偶数长度的回文子串应当是分开计算的(因为回文串两侧同时各去掉一个字符,依然是回文串,且不改变奇偶性),

所以,需要两次二分,一次二分求得长度为偶数的最长回文子串(的长度),再一次二分求得长度为奇数的最长回文子串(的长度)。

最后输出两者中大的即可。

AC代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef unsigned long long ull; const int P=;
const int maxn=+; int len;
char s[maxn];
int q; ull pre[maxn],suf[maxn],Ppow[maxn];
void pretreat()
{
pre[]=;
suf[]=;
Ppow[]=;
for(int i=;i<=len;i++)
{
pre[i]=pre[i-]*P+(s[i]-'a'+);
suf[i]=suf[i-]*P+(s[len-i+]-'a'+);
Ppow[i]=Ppow[i-]*P;
}
} bool found(int x)
{
for(int l1=;l1+x-<=len;l1++)
{
int r1=l1+x-;
int r2=len-l1+,l2=r2-x+;
ull A=pre[r1]-pre[l1-]*(Ppow[x]);
ull B=suf[r2]-suf[l2-]*(Ppow[x]);
if(A==B) return ;
}
return ;
} int main()
{
int kase=;
while(scanf("%s",s+) && s[]!='E')
{
len=strlen(s+);
pretreat(); int l=,r=len/,mid;
while(l<r)
{
mid=(l+r)/+;
if(found(*mid)) l=mid;
else r=mid-;
}
int ans1=l*; l=,r=(len-)/;
while(l<r)
{
mid=(l+r)/+;
if(found(*mid+)) l=mid;
else r=mid-;
}
int ans2=l*+; printf("Case %d: %d\n",++kase,max(ans1,ans2));
}
}

POJ 3974 - Palindrome - [字符串hash+二分]的更多相关文章

  1. Palindrome POJ - 3974 (字符串hash+二分)

    Andy the smart computer science student was attending an algorithms class when the professor asked t ...

  2. POJ 3974 Palindrome 字符串 Manacher算法

    http://poj.org/problem?id=3974 模板题,Manacher算法主要利用了已匹配回文串的对称性,对前面已匹配的回文串进行利用,使时间复杂度从O(n^2)变为O(n). htt ...

  3. POJ 1159 Palindrome(字符串变回文:LCS)

    POJ 1159 Palindrome(字符串变回文:LCS) id=1159">http://poj.org/problem? id=1159 题意: 给你一个字符串, 问你做少须要 ...

  4. 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774

    Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...

  5. POJ 1743 Musical Theme (字符串HASH+二分)

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15900   Accepted: 5494 De ...

  6. POJ 3974 Palindrome

    D - Palindrome Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Sub ...

  7. POJ 3865 - Database 字符串hash

    [题意] 给一个字符串组成的矩阵,规模为n*m(n<=10000,m<=10),如果某两列中存在两行完全相同,则输出NO和两行行号和两列列号,否则输出YES [题解] 因为m很小,所以对每 ...

  8. POJ 3974 Palindrome (算竞进阶习题)

    hash + 二分答案 数据范围肯定不能暴力,所以考虑哈希. 把前缀和后缀都哈希过之后,扫描一边字符串,对每个字符串二分枚举回文串长度,注意要分奇数和偶数 #include <iostream& ...

  9. POJ 3974 Palindrome(最长回文子串)

    题目链接:http://poj.org/problem?id=3974 题意:求一给定字符串最长回文子串的长度 思路:直接套模板manacher算法 code: #include <cstdio ...

随机推荐

  1. Backbone hello world

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http ...

  2. jQuery的deferred对象详解(转)

    jQuery的开发速度很快,几乎每半年一个大版本,每两个月一个小版本. 每个版本都会引入一些新功能.今天我想介绍的,就是从jQuery 1.5.0版本开始引入的一个新功能----deferred对象. ...

  3. oracle登陆提示“ora-01031 insufficient privileges”

    本机装了服务端的oracle11.2g,一直没用,中间换过系统的登陆用户.今早发现登陆数据库时发现老提示“ora-01031 insufficient privileges”,以为监听没配置好,试过了 ...

  4. awk的些许小技巧

    一句话kill掉名为navimain进程的shell脚本(利用awk的列操作能力) `ps|grep navimain | awk 'NR==1 {print $1}'`

  5. Socket网络编程--聊天程序(3)

    上一小节,已经讲到可以每个人多说话,而且还没有限制,简单的来说,我们已经完成了聊天的功能了,那么接下来我们要实现什么功能呢?一个聊天程序至少应该支持一对多的通讯吧,接下来就实现多个客户端往服务器发送数 ...

  6. pycharm启动慢 –xms -xmx相关参数设置

    Eclipse崩溃,错误提示:MyEclipse has detected that less than 5% of the 64MB of Perm Gen (Non-heap memory) sp ...

  7. java框架篇---hibernate之连接池

    Hibernate支持第三方的连接池,官方推荐的连接池是C3P0,Proxool,以及DBCP.在配置连接池时需要注意的有三点: 一.Apche的DBCP在Hibernate2中受支持,但在Hiber ...

  8. MapReduce教程(二)MapReduce框架Partitioner分区<转>

    1 Partitioner分区 1.1 Partitioner分区描述 在进行MapReduce计算时,有时候需要把最终的输出数据分到不同的文件中,按照手机号码段划分的话,需要把同一手机号码段的数据放 ...

  9. 查看SQL SERVER数据库的连接数

    1,查看连接到‘TestDB2’数据库的连接 select * from master.dbo.sysprocesses where dbid = DB_ID('TestDB2') *查询某个数据库用 ...

  10. 牛客网_Go语言相关练习_判断&选择题(5)

    一.判断题 defer应该在if后面,如果文件为空,close会崩溃. package main import ( "os" "fmt" ) func main ...