POJ 3974 - Palindrome - [字符串hash+二分]
题目链接:http://poj.org/problem?id=3974
Time Limit: 15000MS Memory Limit: 65536K
Description
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
Output
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+二分]的更多相关文章
- Palindrome POJ - 3974 (字符串hash+二分)
Andy the smart computer science student was attending an algorithms class when the professor asked t ...
- POJ 3974 Palindrome 字符串 Manacher算法
http://poj.org/problem?id=3974 模板题,Manacher算法主要利用了已匹配回文串的对称性,对前面已匹配的回文串进行利用,使时间复杂度从O(n^2)变为O(n). htt ...
- POJ 1159 Palindrome(字符串变回文:LCS)
POJ 1159 Palindrome(字符串变回文:LCS) id=1159">http://poj.org/problem? id=1159 题意: 给你一个字符串, 问你做少须要 ...
- 字符串hash + 二分答案 - 求最长公共子串 --- poj 2774
Long Long Message Problem's Link:http://poj.org/problem?id=2774 Mean: 求两个字符串的最长公共子串的长度. analyse: 前面在 ...
- POJ 1743 Musical Theme (字符串HASH+二分)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 15900 Accepted: 5494 De ...
- POJ 3974 Palindrome
D - Palindrome Time Limit:15000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ 3865 - Database 字符串hash
[题意] 给一个字符串组成的矩阵,规模为n*m(n<=10000,m<=10),如果某两列中存在两行完全相同,则输出NO和两行行号和两列列号,否则输出YES [题解] 因为m很小,所以对每 ...
- POJ 3974 Palindrome (算竞进阶习题)
hash + 二分答案 数据范围肯定不能暴力,所以考虑哈希. 把前缀和后缀都哈希过之后,扫描一边字符串,对每个字符串二分枚举回文串长度,注意要分奇数和偶数 #include <iostream& ...
- POJ 3974 Palindrome(最长回文子串)
题目链接:http://poj.org/problem?id=3974 题意:求一给定字符串最长回文子串的长度 思路:直接套模板manacher算法 code: #include <cstdio ...
随机推荐
- 【转载】ASP.NET MVC的过滤器【Filters】
文章来自: http://www.cnblogs.com/HopeGi/p/3342083.html 这篇对Filters讲的很详细.正好我自己也不用写了,真的很棒的一篇文章 APS.NET MVC中 ...
- ES6,新增数据结构Map的用法
Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是”字符串-值“对,属性只能是字符串,如果传个对象字面量作为属性名,那么会默认把对象转换成字符串,结果这个属性名就变成 ...
- sql操作总结
SQL 语句的多表查询方式例如:按照 department_id 查询 employees(员工表)和 departments(部门表)的信息.方式一(通用型):SELECT ... FROM ... ...
- 【emWin】例程十二:FontCvt生成字库
介绍: 本例程介绍使用官方字库生成软件FontCvt5.22生成字库文件,并在液晶上显示文字. 实验指导书及代码包下载: 链接:http://pan.baidu.com/s/1eSkliDW 密码:o ...
- SwingWorker
Swing应用程序员常见的错误是误用Swing事件调度线程(Event DispatchThread,EDT).他们要么从非UI线程访问UI组件:要么不考虑事件执行顺序:要么不使用独立任务线程而在ED ...
- vue.js在visual studio 2017下的安装
1.打开"工具"菜单->"NuGet 包管理器"->"管理解决方案 Nuget 的程序包": 在红色标识的地方输入vue: 2. ...
- precision scale
precision意为“精密度.精确”(精度),表示该字段的有效数字位数了. scale意为“刻度.数值范围”(),表示该字段的小数位数. 举个简单的例子 123.45:precision = 5 , ...
- Java知多少(55)线程
和其他多数计算机语言不同,Java内置支持多线程编程(multithreaded programming). 多线程程序包含两条或两条以上并发运行的部分.程序中每个这样的部分都叫一个线程(thread ...
- Json Web Token(JWT)
Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(Si ...
- 开发过程中遇到的问题1--------我们的mysql的查询语句时自己写的,没有用oracle的nextvalue函数。所以这里涉及到了并发的问题。
效果http://www.cnblogs.com/wanggangblog/p/4037543.html 很多的采购单会生成.生成的时候会有订单的编号,然后一个采购单的编号是唯一的,怎么生成呢?之前o ...