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} ...
随机推荐
- 使用certbot申请免费SSL证书
现在网站使用https已经成为标配,但是SSL证书最便宜的DV证书也要几百块钱一年,对于个人开发者来说很不划算.好在,我们有Let's Encrypt,它是能提供免费的SSL证书,应该也是市面上使用最 ...
- SFE人才需要具备哪些能力
SFE(销售队伍效力)人才在企业中扮演着至关重要的角色,他们需要具备一系列的能力来确保销售队伍的高效运作和业绩提升.关于SFE的角色和能力,可以从业务理解.数据洞察.向上管理以及效率提升等几个方面来通 ...
- 原生JS点名器,随机数
因为工作内容的需要自己琢磨了一个随机数的点名器,很早就写出了一版,今天无意间又看到了之前写的代码,还是有很多bug的,今天做了完善在这里分享给大家 <script type="text ...
- 安卓导出已安装app的apk
安卓导出已安装应用APK 有时候想看看别人的APK里面的资源文件或者是逆向,首先就得先搞到APK文件 两种方法获取手机上已安装应用的APK文件 通过adb命令 首先把目标手机连接上电脑 在终端输入 a ...
- .NET 8 中的 ASP.NET Core 指标与 Grafana 仪表板入门
.NET 8 中的 ASP.NET Core 指标与 Grafana 仪表板入门 原文地址:https://devblogs.microsoft.com/dotnet/introducing-aspn ...
- 2024年1月Java项目开发指南8:统一数据返回格式
有时候返回一个字符串,有时候返回一串数字代码,有时候返回一个对象-- 不过怎么说,我们返回的内容往往具有三个 1.消息代码 code 2.消息内容 msg 3.数据内容 data 接下来,我们要编写一 ...
- Vscode实现应用qss样式表
qss简介 qss(Qt Style Sheets)是一种基于CSS的样式语言,用于描述用户界面元素的外观和感觉.qss可以让用户在不修改代码的情况下,轻松地自定义应用程序的外观. 其语法基本如下: ...
- Macos 安装md5sum、sha1sum、md5deep、sha1deep
一.安装md5sum和sha1sum 方法一:brew 安装 # brew install md5sha1sum 方法二:编译安装 源码下载地址:http://www.microbrew.org/to ...
- 【转载】基于timestamp和nonce的防重放攻击
https://www.cnblogs.com/mymelody/p/7325325.html 以前总是通过timestamp来防止重放攻击,但是这样并不能保证每次请求都是一次性的.今天看到了一篇 ...
- Qt编写的modbus模拟器/支持网络和串口以及websocket/支持网络rtu
一.使用说明 1.1 设备模拟-Com 第一步,填写要模拟的设备地址,0表示自动处理,也就是收到什么地址就应答什么地址. 第二步,填写对应的串口号和波特率. 第三步,单击打开串口,成功后会变成关闭串口 ...