题目链接: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. 《Redis入门指南(第2版)》读后感

    今天刚刚将此书看完,现在还能记住一些内容,还有一些感慨感想,正好又想写点什么了就随便记录一下吧!也许灵感明天就消失了呢? 首先觉得作者非常的厉害,年纪轻轻的就写出了这么一本非常不错的书籍! 然后就是对 ...

  2. C# MD5 加密,解密

    //生成cs文件 public class MD5Help { ///MD5加密 public static string MD5Encrypt(string pToEncrypt, string s ...

  3. Nginx 设置域名转向配置

    #运行用户 #user www-data; #启动进程,通常设置成和cpu的数量相等 worker_processes 2; #全局错误日志及PID文件 error_log logs/error.lo ...

  4. sringboot项目在tomcat上的部署

    sringboot项目在tomcat上的部署原文链接: https://blog.csdn.net/zhaoyahui_666/article/details/78283559#comments 20 ...

  5. C++赋值兼容原则

    C++赋值兼容原则(派生类对象是基类对象,反之不成立) –基类指针强制转换成派生类指针 –派生类中重定义基类成员(同名覆盖) 假设, 一个基类 "普通人", 一个派生类 " ...

  6. Eclipse和MyEclipse工程描述符.classpath和.project和.mymetadata详解(转)

    转自:http://blog.csdn.net/zygsee/archive/2009/12/22/5046100.aspx 有时候在一个Java工程里我们需要加入第三方jar包,这时你加入的最好相对 ...

  7. 将png图片转换为字体图标

    字体图标不仅可以随意调整大小,而且可以避免在页面制作过程中引用N多的图片,发送请求造成的流量浪费,因此,我们可以将图标的icon转换成字体图标: 方法一: 1.将png格式的图片转换成svg格式: 网 ...

  8. Java知多少(42)泛型通配符和类型参数的范围

    本节先讲解如何限制类型参数的范围,再讲解通配符(?). 类型参数的范围 在泛型中,如果不对类型参数加以限制,它就可以接受任意的数据类型,只要它是被定义过的.但是,很多时候我们只需要一部分数据类型就够了 ...

  9. Image Lazy Load:那些延时加载图片的开源插件(jQuery)

    图片延时加载技术对大流量的网站来说是十分实用的.目前图片在网站中大量使用,如果不加处理的话会对服务器和带宽造成级大压力,通过只渲染当前用户可见区域的图片,可以极大地减少网站的请求数,降低网络带宽资源. ...

  10. 【转】Winform程序未捕获异常解决方法 EventType clr20r3 P1

    from:http://blog.csdn.net/chichaodechao/article/details/8294922 在开发winform程序时,用到多线程,在服务器部署后运行,老是自动关才 ...