ABB:KMP 的做法非常巧妙。

哈希

思路

显然正着做一遍哈希,倒着做一遍哈希,然后枚举回文中心即可。

时间复杂度 \(O(n)\)。

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define lc (p<<1)
#define rc ((p<<1)|1)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const int N=400005;
const ull base=13331;
ull phash[N],shash[N],pw[N];
int n,ans;
char s[N];
void dohash()
{
pw[0]=1;
for(int i=1;i<N;i++)pw[i]=pw[i-1]*base;
for(int i=1;i<=n;i++)phash[i]=phash[i-1]*base+s[i];
for(int i=n;i>=1;i--)shash[i]=shash[i+1]*base+s[i];
}
ull gethash(int op,int l,int r)
{
if(op==0)return (phash[r]-phash[l-1]*pw[r-l+1]);
return (shash[l]-shash[r+1]*pw[r-l+1]);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>s+1;
ans=n-1;
if(n==1)
{
cout<<0;
return 0;
}
dohash();
for(int i=1;i<=n;i++)
{
if(i-1>=n-(i+1)+1)
{
int len=n-(i+1)+1;
if(gethash(0,i-1-len+1,i-1)==gethash(1,i+1,i+1+len-1))
{
ans=min(ans,i-1-len);
}
}
if(i>=n-(i+1)+1)
{
int len=n-(i+1)+1;
if(gethash(0,i-len+1,i)==gethash(1,i+1,i+1+len-1))
{
ans=min(ans,i-len);
}
}
}
cout<<ans;
return 0;
}

哈希的代码又臭又长,肯定不是这题的最优解。

KMP

思路

我们考虑这题要求的本质是什么,显然是求字符串 \(s\) 最长的回文后缀的长度 \(l\),那么答案就是 \(n-l\)。因为剩下的那些必须对称过去。

那么如何求最长的回文后缀呢?我们可以先把字符串 \(s\) 反转为 \(s'\),把后缀转化为前缀便于处理。

由于回文串正着读和反着读都一样,可以发现回文后缀满足是字符串 \(s'\) 的一段前缀,也是字符串 \(s\) 的一段后缀

因此如果字符串 \(s'\) 的一段前缀与字符串 \(s\) 的一段后缀相等,就说明这是一个合法的回文后缀。

如果要让这个后缀最长,那么显然是 KMP 的 \(next_n\),就求出来了。

实现上,我们可以将最后的主串设置为 \(s'\) 与任意一个分隔符与 \(s\) 拼接起来的字符串,然后做一遍 KMP 即可。

时间复杂度 \(O(n)\)。

代码

非常简短,注意字符串开两倍的长度。

#include <bits/stdc++.h>
using namespace std;
const int N=800005;
int n,ne[N];
char s[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>s+n+2;
s[n+1]='%';
for(int i=1,j=2*n+1;i<=n;i++,j--)s[i]=s[j];
int now=0;
for(int i=2;i<=2*n+1;i++)
{
while(now&&s[now+1]!=s[i])now=ne[now];
if(s[now+1]==s[i])now++;
ne[i]=now;
}
cout<<n-ne[2*n+1];
return 0;
}

Luogu P9606 CERC2019 ABB 题解 [ 绿 ] [ KMP ] [ 字符串哈希 ]的更多相关文章

  1. UVA - 11475 Extend to Palindrome —— 字符串哈希 or KMP or 后缀数组

    题目链接:https://vjudge.net/problem/UVA-11475 题意: 给出一个字符串,问在该字符串后面至少添加几个字符,使得其成为回文串,并输出该回文串. 题解: 实际上是求该字 ...

  2. 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)

    洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...

  3. KMP字符串模式匹配详解(转)

    来自CSDN     A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度 ...

  4. 字符串哈希及KMP

    字符串很神奇,因为它在计算机中应用很广泛,就每一个程序都需要用到字符串,所以学好字符串是非常重要的. 接下来就介绍两个字符串的基本操作 1:字符串hash  一种可以查找几个字符串有几个不同的字符串. ...

  5. BM和KMP字符串匹配算法学习

    BM和KMP字符串匹配算法学习 分类: 研究与学习 字符串匹配BM(Boyer-Moore)算法学习心得 http://www.cnblogs.com/a180285/archive/2011/12/ ...

  6. KMP字符串模式匹配详解(zz)

    刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN     A_B_ ...

  7. KMP字符串模式匹配详解

    KMP字符串模式匹配详解 http://www.cppblog.com/oosky/archive/2006/07/06/9486.html

  8. Luogu P4503 [CTSC2014]企鹅QQ(字符串哈希)

    P4503 [CTSC2014]企鹅QQ 题面 题目背景 \(PenguinQQ\) 是中国最大.最具影响力的 \(SNS(Social Networking Services)\) 网站,以实名制为 ...

  9. HDU 1880 题解(字符串哈希)

    题面: 魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  10. 【CodeForces】961 F. k-substrings 字符串哈希+二分

    [题目]F. k-substrings [题意]给定长度为n的串S,对于S的每个k-子串$s_ks_{k+1}...s_{n-k+1},k\in[1,\left \lceil \frac{n}{2} ...

随机推荐

  1. confd+Nacos实现nginx配置文件管理

    场景: 由于公司内部站点保护的需求, 将部分的站点添加白名单, 这边的操作是在nginx配置文件中添加如下代码 allow 127.0.0.1: deny all; 但随之问题也出现了, 需要添加一个 ...

  2. webpack之基本使用

    webpack是一个模块打包器(module bundler),webpack视HTML,JS,CSS,图片等文件都是一种 资源 ,每个资源文件都是一个模块(module)文件,webpack就是根据 ...

  3. docker安装cas

    直接docker pull apereo/cas ,docker run的时候各种报错: standard_init_linux.go:178: exec user process caused &q ...

  4. 云数据备份 | CDN 日志备份最佳实践

    前言 ​ 内容分发网络(Content Delivery Network,CDN),是在现有 Internet 中增加的一层新的网络架构,可以有效降低用户访问延迟,提升可用性. CDN 按照小时粒度对 ...

  5. vue 相同路由不同参数跳转时,不刷新

    在公共的router-view上加 :key="$route.fullPath  控制key属性变化

  6. 小程序canvas白屏解决(

    造成canvas白屏的原因(两个原因) 1. 使用网络图片经绘制,没有配置downloadfile域名 ctx.drawImage('https://img1.imgtn.bdimg.com/it/u ...

  7. 好消息,在 Visual Studio 中可以免费使用 GitHub Copilot 了!

    前言 今天大姚给大家分享一个好消息,GitHub Copilot 可以免费使用了!在此之前若开发者要使用 GitHub Copilot 需要付费订阅,每月订阅费用起步价为 10 美元,而经过验证的学生 ...

  8. 中电金信智能视觉分析系统,以AI技术助力企业升级

    ​ 基于行业需求与业务痛点,中电金信推出了智能视觉分析系统.该系统是集视频接入.视频识别与分析.AI算法管理.异常报警等为一体,可提供视频安全监管标准的场景应用方案以及二次开发能力的通用智能视觉分析系 ...

  9. 【C#】【类设计器】【类图】类图安装与简单使用

    安装 使用 Ctrl + Shift + A 或者按下图操作

  10. 【MyBatis】学习笔记06:各种查询所返回数据的数据类型

    [Mybatis]学习笔记01:连接数据库,实现增删改 [Mybatis]学习笔记02:实现简单的查 [MyBatis]学习笔记03:配置文件进一步解读(非常重要) [MyBatis]学习笔记04:配 ...