题目链接: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测试

    //这个方法会多一次 public function testRedisList(){ $num = 10; $user_id = uniqid(); //直接链接本地的redis $redis = ...

  2. 让ASP.NET Web API支持$format参数的方法

    在不使用OData的情况下,也可以让ASP.NET Web API支持$format参数,只要在WebApiConfig里添加如下三行红色粗体代码即可: using System; using Sys ...

  3. Spring Boot 2.0 整合 FreeMarker 模板引擎

    本篇博文将和大家一起使用Spring Boot 2.0 和FreeMarker 模板引擎整合实战. 1. 创建新的项目 2. 填写项目配置信息 3. 勾选web 模块 4. 勾选freemarker模 ...

  4. 对ThreadLocal实现原理的一点思考

    前言 在<透彻理解Spring事务设计思想之手写实现>中,已经向大家揭示了Spring就是利用ThreadLocal来实现一个线程中的Connection是同一个,从而保证了事务.本篇博客 ...

  5. 【Android】GPS定位基本原理浅析

    位置服务已经成为越来越热的一门技术,也将成为以后所有移动设备(智能手机.掌上电脑等)的标配.而定位导航技术中,目前精度最高.应用最广泛的,自然非GPS莫属了.网络上介绍GPS原理的专业资料很多,而本文 ...

  6. 解剖 Elasticsearch 集群 - 之一

    解剖 Elasticsearch 集群 - 之一 本篇文章是一系列涵盖 Elasticsearch 底层架构和原型示例的其中一篇.在本篇文章中,我们会讨论底层的存储模型以及 CRUD(创建.读取.更新 ...

  7. WPF Input Validation Using MVVM

    Data validation is a key part in WPF.Validation is used to alert the user that the data he entered i ...

  8. c++ 动态判断基类指针指向的子类类型(typeid)

    我们在程序中定义了一个基类,该基类有n个子类,为了方便,我们经常定义一个基类的指针数组,数组中的每一项指向都指向一个子类,那么在程序中我们如何判断这些基类指针是指向哪个子类呢? 本文提供了两种方法 ( ...

  9. Linux CentOS 6.9 Minimal 编译 OpenJDK 7

    今天学习<深入理解Java虚拟机:JVM高级特性与最佳实践>一书,并动手在Linux系统上编译OpenJDK 7,初次搞不太顺利,特记录下编译操作细节. 一.前期准备 约定:工具默认安装目 ...

  10. 经典的HTML5游戏及其源码分析

    HTML5已经相当强大,在HTML5平台上,我们可以完成很多非常复杂的动画效果,包括游戏在内.早期我们只能利用flash来实现网络游戏,现在我们又多了一种选择,即用HTML5制作游戏.相比flash, ...