Luogu P9606 CERC2019 ABB 题解 [ 绿 ] [ KMP ] [ 字符串哈希 ]
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 ] [ 字符串哈希 ]的更多相关文章
- UVA - 11475 Extend to Palindrome —— 字符串哈希 or KMP or 后缀数组
题目链接:https://vjudge.net/problem/UVA-11475 题意: 给出一个字符串,问在该字符串后面至少添加几个字符,使得其成为回文串,并输出该回文串. 题解: 实际上是求该字 ...
- 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)
洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...
- KMP字符串模式匹配详解(转)
来自CSDN A_B_C_ABC 网友 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法.简单匹配算法的时间复杂度为O(m*n);KMP匹配算法.可以证明它的时间复杂度 ...
- 字符串哈希及KMP
字符串很神奇,因为它在计算机中应用很广泛,就每一个程序都需要用到字符串,所以学好字符串是非常重要的. 接下来就介绍两个字符串的基本操作 1:字符串hash 一种可以查找几个字符串有几个不同的字符串. ...
- BM和KMP字符串匹配算法学习
BM和KMP字符串匹配算法学习 分类: 研究与学习 字符串匹配BM(Boyer-Moore)算法学习心得 http://www.cnblogs.com/a180285/archive/2011/12/ ...
- KMP字符串模式匹配详解(zz)
刚看到位兄弟也贴了份KMP算法说明,但本人觉得说的不是很详细,当初我在看这个算法的时候也看的头晕昏昏的,我贴的这份也是网上找的.且听详细分解: KMP字符串模式匹配详解 来自CSDN A_B_ ...
- KMP字符串模式匹配详解
KMP字符串模式匹配详解 http://www.cppblog.com/oosky/archive/2006/07/06/9486.html
- Luogu P4503 [CTSC2014]企鹅QQ(字符串哈希)
P4503 [CTSC2014]企鹅QQ 题面 题目背景 \(PenguinQQ\) 是中国最大.最具影响力的 \(SNS(Social Networking Services)\) 网站,以实名制为 ...
- HDU 1880 题解(字符串哈希)
题面: 魔咒词典 Time Limit: 8000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- 【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} ...
随机推荐
- golang之循环导包
作为一个 Golang 开发,你可能在项目中遇到过包的循环依赖问题.Golang 不允许循环依赖,如果检测到代码中存在这种情况,在编译时就会抛出异常. 循环依赖 假设我们有两个包:p1和p2.当包p1 ...
- Mybatis【14】-- Mybatis如何实现一对多查询?
++注:代码已托管在GitHub上,地址是:https://github.com/Damaer/Mybatis-Learning ,项目是mybatis-10-one2many,需要自取,需要配置ma ...
- Konva.js
1.前言 简介:Konva.js - 适用于桌面/移动端应用的 HTML5 2d canvas 库 个人体验:原生的canvas只支持绘制基本的直线,矩形,文字,图片,扇形等,如果要支持更复杂的功能, ...
- Tomcat 已集成 CROS Fitler ExpiresFilter 等一堆常用 Filter
http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html 再也不需要三方包提供的 filter 了
- 【Python】【爬虫】【爬狼】005_爬取数据处理-有的链接缺少了“http”的解决方案(not in)
我认为这一篇文章是没有意义的,说白了就是判断字符串是否包含指定内容. 爬图片链接的时候,发现了一个问题 有的链接缺了http 像我这种使用HTML表格输出的,本来是可以把图片链接显示为图片的,但是有的 ...
- HBaseIntrospector
package x;import java.sql.DatabaseMetaData; import java.sql.ResultSet; import java.sql.SQLException; ...
- SM国密算法
package com.abc.apollo.common.util; import javax.crypto.IllegalBlockSizeException; import java.secur ...
- Python+Selenium模拟人工抓取数据
Selenium 是一个用于Web应用程序测试的工具.Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Fire ...
- Qt编写地图综合应用36-覆盖物折线
一.前言 折线图目前应用最广的也是用来绘制各种轨迹,折线图其实就是后面动态轨迹图.飞机航线图的前身,公用的一个方法addPolyline,折线图可以设置颜色.粗细.透明度等属性,如果开启了悬浮绘图工具 ...
- Qt编写安防视频监控系统21-摄像机管理
一.前言 摄像机管理在整个系统中是数据库部分最核心的,只有添加了摄像机信息,才能进行加载,生成树状列表等,摄像机表信息的字段内容改过好几次,有可能后期还需要修改,目前摄像机表信息主要包括摄像机编号.摄 ...