D - Palindrome

Time Limit:15000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

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

求最长回文串的长度。

(manacher算法)

#include<cstdio>
#include<cstring>
#include<iostream>
#define m(s) memset(s,0,sizeof s);
using namespace std;
const int N=1e6+;
int l,cas,len,p[N<<];
char s[N],S[N<<];
void manacher(){
int ans=,id=,mx=-;
for(int i=;i<l;i++){
if(id+mx>i) p[i]=min(p[id*-i],id+mx-i);
while(i-p[i]->=&&i+p[i]+<=l&&S[i-p[i]-]==S[i+p[i]+]) p[i]++;
if(id+mx<i+p[i]) id=i,mx=p[i];
ans=max(ans,p[i]);
}
printf("Case %d: %d\n",++cas,ans);
}
int main(){
while(scanf("%s",s)==){
if(s[]=='E') break;
len=strlen(s);m(p);m(S);
l=-;
for(int i=;i<len;i++) S[++l]='#',S[++l]=s[i];
S[++l]='#';
manacher();
}
return ;
}

//====================================================

//hash有点慢
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef int i64;
const int N=1e6+;
int n,m,cas,ans,a[N<<];char s[N];
i64 P,pow[N<<],hash_l[N<<],hash_r[N<<];
void get_hash(){
pow[]=;hash_r[]=hash_l[m+]=;
for(int i=;i<=m;i++) pow[i]=pow[i-]*P;
for(int i=;i<=m;i++) hash_r[i]=hash_r[i-]*P+a[i];
for(int i=m;i>=;i--) hash_l[i]=hash_l[i+]*P+a[i]; }
int main(){
P=;
while(scanf("%s",s+)==){
if(s[]=='E') break;
n=strlen(s+);ans=m=;
for(int i=;i<=n;i++){
a[++m]='#';
a[++m]=s[i]-'a';
}
a[++m]='#';
get_hash();
int l,r,mid;
for(int i=;i<=m;i++){
l=;
if(i-<m-i) r=i;
else r=m-i+;
while(r-l>){
mid=l+r>>;
i64 hash_to_l=hash_r[i-]-hash_r[i-mid-]*pow[mid];
i64 hash_to_r=hash_l[i+]-hash_l[i+mid+]*pow[mid];
if(hash_to_l==hash_to_r) l=mid;
else r=mid;
}
ans=max(ans,l);
}
printf("Case %d: %d\n",++cas,ans);
}
return ;
}

POJ 3974 Palindrome的更多相关文章

  1. POJ 3974 - Palindrome - [字符串hash+二分]

    题目链接:http://poj.org/problem?id=3974 Time Limit: 15000MS Memory Limit: 65536K Description Andy the sm ...

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

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

  3. ●POJ 3974 Palindrome(Manacher)

    题链: http://poj.org/problem?id=3974 题解: Manacher 求最长回文串长度. 终于会了传说中的马拉车,激动.推荐一个很棒的博客:https://www.61mon ...

  4. POJ 3974 Palindrome 字符串 Manacher算法

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

  5. poj 3974 Palindrome (manacher)

    Palindrome Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 12616   Accepted: 4769 Desc ...

  6. 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome

    题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...

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

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

  8. POJ 3974 Palindrome | 马拉车模板

    给一个字符串,求最长回文字串有多长 #include<cstdio> #include<algorithm> #include<cstring> #define N ...

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

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

随机推荐

  1. 访问SAP的Domain的Value Range

    访问Domain的Value Range有两种方法: 1.直接访问表 dd07l和dd07T     select * from dd07l            where domname   = ...

  2. MapGIS转Shp文件的单位问题

    在MapGIS浏览查看一下数据,各种不习惯:用mapgis自带的转shp功能,属性表会出错:利用名为map2shp的试用版软件可将mapgis格式的数据较为良好转成shp格式.但经常会遇到一个单位问题 ...

  3. ArcObject10.1降级至10.0

    最开始接触ArcGIS版本是9.3,为了需要也安装了9.2进行开发:因为自己的电脑配置较低,所以跑不起10.0中文版:毕业工作后,行业内用10.1居多(虽然10.3已出):现在10.4都要出来了:由于 ...

  4. CRM 2013 Reporting Extensions for SSRS 安装及问题解决

    说明一下 Reporting Extensions for SSRS 安装过程. 安装目录在安装目录下 SrsDataConnector 下.如果是CRM 2013安装中运行,可以跳过此步. 此外在说 ...

  5. 在Java中调用C

    在Java代码中通过JNI调用C函数的步骤如下: 第一步:编写Java代码 第二步:编译Java代码(javac Java文件) 第三步:生成C代码头文件(javah java类名,自动生成) 第四步 ...

  6. 极光推送和百度lbs android sdk一起使用使用proguard 混淆的问题

    主要是http得类被混淆后,导致apk定位失败.经过确认,保留apache 的http类就好了 # To enable ProGuard in your project, edit project.p ...

  7. iOS 编译报错

    Undefined symbols for architecture i386: “_OBJC_CLASS_$_XXX”, referenced from: objc-class-ref in XXX ...

  8. 多线程基础(五)NSThread线程通信

    5.多线程基础 线程间通信   什么叫线程间通信 在一个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信   线程间通信的体现 1个线程传递数据给另一个线程 在1个线程中执行完特定任务后, ...

  9. javascript 依次输入自动定焦框

    <html> <head> <script type="text/javascript"> function moveNext(object,i ...

  10. Linux与Windows共享文件夹之samba的安装与使用(Ubuntu为例)

    1.写在前面     当你在Windows上安装了一台Linux的虚拟机,你想访问Linux中的文件夹,将虚拟机中的文件复制到Windows主机上,你会怎么做呢?如果这台Linux主机不是虚拟机,而是 ...