题目链接 : https://www.acwing.com/problem/content/141/

#include <bits/stdc++.h>
using namespace std; const int MAXN = ;
const int N = ; struct Palindromic_Tree {
//cnt最后count一下之后是那个节点代表的回文串出现的次数
int next[MAXN][N] ;//next指针,next指针和字典树类似,指向的串为当前串两端加上同一个字符构成
int fail[MAXN] ;//fail指针,失配后跳转到fail指针指向的节点
int cnt[MAXN] ; //表示节点i表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的)
int num[MAXN] ; //表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数
int len[MAXN] ;//len[i]表示节点i表示的回文串的长度(一个节点表示一个回文串)
int S[MAXN] ;//存放添加的字符
int last ;//指向新添加一个字母后所形成的最长回文串表示的节点。
int n ;//表示添加的字符个数。
int p ;//表示添加的节点个数。 int newnode ( int l ) {//新建节点
for ( int i = ; i < N ; ++ i ) next[p][i] = ;
cnt[p] = ;
num[p] = ;
len[p] = l ;
return p ++ ;
} void init () {//初始化
p = ;
newnode ( ) ;
newnode ( - ) ;
last = ;
n = ;
S[n] = - ;//开头放一个字符集中没有的字符,减少特判
fail[] = ;
} int get_fail ( int x ) {//和KMP一样,失配后找一个尽量最长的
while ( S[n - len[x] - ] != S[n] ) x = fail[x] ;
return x ;
} void add ( int c ) {
c -= 'a' ;
S[++ n] = c ;
int cur = get_fail ( last ) ;//通过上一个回文串找这个回文串的匹配位置
if ( !next[cur][c] ) {//如果这个回文串没有出现过,说明出现了一个新的本质不同的回文串
int now = newnode ( len[cur] + ) ;//新建节点
fail[now] = next[get_fail ( fail[cur] )][c] ;//和AC自动机一样建立fail指针,以便失配后跳转
next[cur][c] = now ;
num[now] = num[fail[now]] + ;
}
last = next[cur][c] ;
cnt[last] ++ ;
} void count () {
for ( int i = p - ; i >= ; -- i ) cnt[fail[i]] += cnt[i] ;
//父亲累加儿子的cnt,因为如果fail[v]=u,则u一定是v的子回文串!
}
} t; int main(){
string str;
int cas = ;
while(cin >> str && str != "END"){
t.init();
for(int i = ;i < str.size(); i ++) t.add(str[i]);
int maxx = ;
for(int i = ;i < t.p;i ++) maxx = max(maxx,t.len[i]);
cout << "Case " << cas ++ << ": " << maxx << endl;
}
return ;
}

前缀和+后缀和+二分+Hash(哈希) O(nlogn)O(nlogn)
我们发现0这道题目数据范围极其恐怖,那么只有一个办法可以让我们求解这道题目,那就是哈希,或者是O(n)O(n)复杂度的Manacher算法,但是我们这道题目是锻炼我们的哈希水平,所以我们这里只说如何用哈希算法求解.作者忘记如何使用马拉车算法了…
上一道兔子兔子兔子的题目,我们知道判断两个字符串是否相等,可以使用字符串哈希,也就是将字符串算成P进制数值,然后区间和判断即可,那么这道题目我们需要一个正的字符串,还需要一个反的字符串,然后如果正字符串等于反的字符串,那么奇数回文串就2+1,偶数回文串就直接2即可.之所以要这么做,因为我们是要回文对不对,我们需要将回文拆解成为一个正字符串和一个反字符串,这样才好处理这道题目.
既然如此,我们可以算出一个前缀和,再算出一个后缀和,然后就可以知道,正字符串和一个反字符串.字符串的哈希值就是这个区间的哈希值和.
算完之后,我们当前就只需要枚举一个mid中间点,因为所有回文串都是有一个中间点(奇),或者中间区间(偶),然后二分分别寻找这个字符串长度即可,记住不是回文串,回文串的长度,是字符串长度* 2 + 1(奇) 或者是字符串长度 * 2(偶数).
切记如果说这个最大回文串为1(也就是所有字符都不一样,比如说abcdefg),那么输出是1,不是3,奇数回文串=奇数字符串*2+1,你们要小心特判这种情况,或者处理二分边界.
C++ 代码

#include <bits/stdc++.h>
using namespace std;
#define ull unsigned long long
#define fir(i,a,b) for(int i=a;i<=b;i++)
#define fic(i,a,b) for(int i=a;i>=b;i--)
#define Mod 131 //P进制
const int N=;
char s[N];
ull f1[N],f2[N],p[N];
int ans,t,l,r,mid;
ull Hash1(int i,int j)//正字符串的哈希值
{
return (f1[j]-f1[i-]*p[j-i+]);
}
ull Hash2(int i,int j)//反字符串的哈希值
{
return (f2[i]-f2[j+]*p[j-i+]);
}
void init()
{
p[]=;//p^0为1
fir(i,,N-)
p[i]=p[i-]*;//P进制的位值
}
int main()
{
init();
while (++t)
{
ans=;
scanf("%s",s+);
int len=strlen(s+);
if (strcmp(s+,"END")==) //结束读入
return ;
f2[len+]=;//初始化要注意,不然的话容易GG
fir(i,,len)
f1[i]=f1[i-]*Mod+(s[i]-'a'+);//前缀和
fic(i,len,)
f2[i]=f2[i+]*Mod+(s[i]-'a'+);//后缀和
fir(i,,len)
{
l=,r=min(i-,len-i);//二分枚举长度为奇数的字符串 记住这里l一定要为0,不然的话,你会发现最后一个数据会卡死你.
while(l<r)
{
mid=l+r+>>;
if (Hash1(i-mid,i-)==Hash2(i+,i+mid))//如果这是一个回文串的话
l=mid;
else
r=mid-;
}
ans=max(l<< | ,ans);//算出最大长度
l=,r=min(i-,len-i+);//偶数字符串
while (l<r)
{
mid=l+r+>>;
if (Hash1(i-mid,i-)==Hash2(i,i+mid-))//check判断
l=mid;
else
r=mid-;
}
ans=max(l<<,ans);//偶数字符串只需要*2
}
printf("Case %d: %d\n",t,ans);
}
return ;
}

139. 回文子串的最大长度(回文树/二分,前缀,后缀和,Hash)的更多相关文章

  1. AcWing:139. 回文子串的最大长度(字符串Hash + 前缀和 + 后缀和 + 二分)

    如果一个字符串正着读和倒着读是一样的,则称它是回文的. 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少. 输入格式 输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个 ...

  2. AcWing 139. 回文子串的最大长度 hash打卡

    如果一个字符串正着读和倒着读是一样的,则称它是回文的. 给定一个长度为N的字符串S,求他的最长回文子串的长度是多少. 输入格式 输入将包含最多30个测试用例,每个测试用例占一行,以最多1000000个 ...

  3. 51NOD 1088 最长回文子串&1089 最长回文子串 V2(Manacher算法)

    回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度. Input 输入Str(Str的长度 <= 1000(第二题要 ...

  4. 51nod1089(最长回文子串之manacher算法)

    题目链接: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1089 题意:中文题诶~ 思路: 我前面做的那道回文子串的题 ...

  5. 【转】最长回文子串的O(n)的Manacher算法

    Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...

  6. 求最长回文子串 - leetcode 5. Longest Palindromic Substring

    写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...

  7. 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

    1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...

  8. Manacher算法 O(n) 求最长回文子串

    转自:http://bbs.dlut.edu.cn/bbstcon.php?board=Competition&gid=23474 其实原文说得是比较清楚的,只是英文的,我这里写一份中文的吧. ...

  9. [转]O(n)回文子串算法 Manacher算法

    这里,我介绍一下O(n)回文串处理的一种方法.Manacher算法.原文地址:http://zhuhongcheng.wordpress.com/2009/08/02/a-simple-linear- ...

随机推荐

  1. CentOS版本禁用Ctrl+Alt+Del重启功能

    1  禁用Ctrl+Alt+Del重启功能(不重启系统的前提条件) 1.1  CentOS 6 ##查看/etc/inittab确认Ctrl+Alt+Del相关配置文件 cat /etc/initta ...

  2. js下拉框选择图片

    二种方式:下拉框里面选项有图片与没有图片 1.用下拉框写  下拉框的option没法添加图片如果下拉框里面不需要图片可以用这种方式. <!DOCTYPE html> <html> ...

  3. less基本用法:持续归纳中

    todo 1,嵌套语法:https://www.w3cschool.cn/less/nested_directives_bubbling.html 简单来说就是可以与html一样去写css,并且会继承 ...

  4. Android学习_7/22

    一.Android项目目录结构 1.         AndroidManifest.xml:整个Android项目的配置,注册各组件 <activity android:name=" ...

  5. 在win7下,将QT集成到vs2010上

    在网上查了很多,自己先是下载了一个5.2.0版本的,但在我的电脑上运行时老报错,一怒之下决定不再使用5.2.0版本的QT,而先择了更低版本的4.8.5版本,然后.....然后就成功了.谢天谢地,在这我 ...

  6. What is the most efficient way to deep clone an object in JavaScript?

    What is the most efficient way to deep clone an object in JavaScript? Reliable cloning using a libra ...

  7. erlang实现排列组合问题

    今天在公司做一个日志分析的任务,在做统计的时候,遇到这样一个问题, 之前已经将数据拆分好,出现这样一张中间表Table,简略写如下: A属性 B属性 C属性 D属性 1       3         ...

  8. 字面常量 kotlin(2)

    字面常量数值常量字面值有以下几种:十进制: 123Long 类型用大写 L 标记: 123L十六进制: 0x0F二进制: 0b00001011注意: 不支持八进制Kotlin 同样支持浮点数的常规表示 ...

  9. 【转】C++友元

    转自:https://www.cnblogs.com/BeyondAnyTime/archive/2012/06/04/2535305.html 1.友元函数的简单介绍 1.1为什么要使用友元函数 在 ...

  10. java:LeakFilling(Springmvc)

    1.后台可以同时多个对象接收前端页面的值:(如图两个都打印了) 2.参数绑定的注解,通过该注解可以解决参数名称与controller中形参名称不一致的问题: @RequestParam(name=&q ...