Codeforces 961F - k-substrings(二分+哈希)
介绍一种奇怪的 \(\Theta(n\log n)\) 的奇怪做法。
注意到这个“border 的长度必须是奇数”的条件非常奇怪,同时我们待求解的字符串也有一些比较奇妙的性质——它们的左右端点都关于中线轴对称,即 \(l+r=n+1\)。我们考虑 border 的性质与 \(l+r=n+1\) 的条件联系起来。对于一个 \(s[l...r]\) 的长度为 \(len\) 的 border(\(len\) 为奇数),假设 \(r'=l+len-1,l'=r-len+1\),那么必然有 \(s_l\) 与 \(s_{l'}\)、\(s_{l+1}\) 与 \(s_{l'+1}\),……,\(s_r\) 与 \(s_{r'}\) 均匹配。在下文中,用“左 border”代替 \(s[l...r']\),“右 border”代替 \(s[l'...r]\)。
然后我们惊奇地发现,如果我们记 \(m_l=\dfrac{l+r'}{2},m_r=\dfrac{l'+r}{2}\),那么有 \(m_l+m_r=n+1\),并且 \(m_l\) 与 \(m_r\) 也应匹配。画出图来大概是这个样子,其中黑线为中线 \(\dfrac{n+1}{2}\),绿线为左 border 的两个端点,褐色的线为右 border 的两个端点:
因此我们考虑枚举 \(m_l\),那么可以发现,由于 \(m_l\) 是左 border 的中点,\(m_r\) 是右 border 的中点,因此在上图中,两段黄色部分对应的字符串必须相同,两段紫色部分也同理,并且黄色和紫色部分长度也应相同。也就是说 \(s[l...m_l],s[l'...m_r]\) 是 \(s[1...m_l],s[1...m_r]\) 两段前缀的 LCS,\(s[m_l...r'],s[m_r...r]\) 是 \([l...n],s[r...n]\) 的两段后缀的 LCP,也就是说,我们可以通过二分+哈希找到 \(s[l...m_l]\) 这段区间的范围,不妨设其为 \([1,mn]\)。得到了这些信息之后,又该怎样求解答案呢?对于每个左端点 \(l\),我们考虑设 \(M_l\) 表示 \([l,n+1-l]\) 的所有长度为奇数的 border 中,左 border 的中点的最大值,显然只要左 border 的中点越靠右,对应的 border 长度也就越大,而不难发现,我们求出 \(m_l,m_r\) 可以延伸的范围 \([1,mn]\) 之后,操作等价于令 \(M_{m_l-mn+1},M_{m_l-mn+2},\cdots,M_{m_l}\) 均对 \(m_l\) 取 \(\max\),差分一下用个 set
维护即可。
const int MAXN=1e6;
const int MOD=1004535809;
const int BS=193;
int n;char s[MAXN+5];
int pw[MAXN+5],hsh[MAXN+5];
vector<int> add[MAXN+5],del[MAXN+5];
int gethsh(int l,int r){return (hsh[r]-1ll*hsh[l-1]*pw[r-l+1]%MOD+MOD)%MOD;}
int main(){
scanf("%d%s",&n,s+1);
for(int i=(pw[0]=1);i<=MAXN;i++) pw[i]=1ll*pw[i-1]*BS%MOD;
for(int i=1;i<=n;i++) hsh[i]=(1ll*hsh[i-1]*BS+s[i])%MOD;
for(int i=1;i<=n>>1;i++) if(s[i]==s[n+1-i]){
int l=1,r=i,L=0,R=0;
while(l<=r){
int mid=l+r>>1;
if(gethsh(i-mid+1,i)==gethsh(n+1-i-mid+1,n+1-i)) L=mid,l=mid+1;
else r=mid-1;
} l=1,r=i;
while(l<=r){
int mid=l+r>>1;
if(gethsh(i,i+mid-1)==gethsh(n+1-i,n-i+mid)) R=mid,l=mid+1;
else r=mid-1;
} int mn=min(L,R);
add[i-mn+1].pb(i);del[i+1].pb(i);
} multiset<int> st;
for(int i=1;i<=(n+1>>1);i++){
for(int x:add[i]) st.insert(x);
for(int x:del[i]) st.erase(st.find(x));
if(st.empty()) printf("-1 ");
else printf("%d ",((*st.rbegin())-i+1)*2-1);
}
return 0;
}
Codeforces 961F - k-substrings(二分+哈希)的更多相关文章
- codeforces 1269E K Integers (二分+树状数组)
链接:https://codeforces.com/contest/1269/problem/E 题意:给一个序列P1,P2,P3,P4....Pi,每次可以交换两个相邻的元素,执行最小次数的交换移动 ...
- 2016vijos 1-1 兔子的字符串(后缀数组 + 二分 + 哈希)
题意: 给出一个字符串,至多将其划分为n部分,每一部分取出字典序最大的子串ci,最小化 最大的ci 先看一个简化版的问题: 给一个串s,再给一个s的子串t,问能否通过将串划分为k个部分,使t成为划分后 ...
- Codeforces 109D String Transformation 字符串 哈希 KMP
原文链接https://www.cnblogs.com/zhouzhendong/p/CF109D.html 题目传送门 - CF109D 题意 给定两个字符串 $a,b$ ,求一组 $i,j$ 使得 ...
- POJ 2774 后缀数组 || 二分+哈希
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 35607 Accepted: 14 ...
- [Codeforces 1199C]MP3(离散化+二分答案)
[Codeforces 1199C]MP3(离散化+二分答案) 题面 给出一个长度为n的序列\(a_i\)和常数I,定义一次操作[l,r]可以把序列中<l的数全部变成l,>r的数全部变成r ...
- CodeForces 670D1 暴力或二分
今天,开博客,,,激动,第一次啊 嗯,,先来发水题纪念一下 D1. Magic Powder - 1 This problem is given in two versions that diff ...
- codeforces 895B XK Segments 二分 思维
codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\( ...
- codeforces 803D Magazine Ad(二分+贪心)
Magazine Ad 题目链接:http://codeforces.com/contest/803/problem/D ——每天在线,欢迎留言谈论. 题目大意: 给你一个数字k,和一行字符 例: g ...
- [JSOI2008]Blue Mary的战役地图(二分+哈希)
Blue Mary最近迷上了玩Starcraft(星际争霸) 的RPG游戏.她正在设法寻找更多的战役地图以进一步提高自己的水平. 由于Blue Mary的技术已经达到了一定的高度,因此,对于用同一种打 ...
随机推荐
- 一站式交付体验:云效+Kubernetes
背景 云效依托于阿里巴巴研发效能多年规模化持续交付,赋能云上开发者专为云端用户提供的一站式研发协作平台.Kubernetes,由Google开源的容器集群管理平台,面向运维侧提供自动化的集群和应用管理 ...
- 2 What is the Domain Driven Design? 什么是领域驱动设计
What is the Domain Driven Design? 什么是领域驱动设计 Domain-driven design (DDD) is an approach to software de ...
- Go语言核心36讲(Go语言进阶技术五)--学习笔记
11 | 通道的高级玩法 我们已经讨论过了通道的基本操作以及背后的规则.今天,我再来讲讲通道的高级玩法. 首先来说说单向通道.我们在说"通道"的时候指的都是双向通道,即:既可以发也 ...
- 4.14——208. 实现 Trie (前缀树)
前缀树(字典树)是经典的数据结构,以下图所示: 本来处理每个节点的子节点集合需要用到set,但是因为输入规定了只有26个小写字母,可以直接用一个[26]的数组来存储. 关于ASCII代码: Java ...
- Less-(38~41) 堆叠注入
首先申明,Less-(38~41)可以采取和Less-(1~4)相同的解法:(一一对应) 然而,他们的漏洞其实更大,我们可以做更多具有破坏性的事情. 代码审计: Less-(38~41): 41的$s ...
- 需求存在,功能存在——Alpha阶段性总结
0.Alpha开发成果 题士Alpha发布报告 题士开发记录 1.任务划分 Alpha阶段大致将任务划分为Design,Develop和Test三类 Design型任务包含页面UI设计和接口API设计 ...
- Beta阶段第九次会议
Beta阶段第九次会议 时间:2020.5.25 完成工作 姓名 完成工作 任务难度 完成度 ltx 1.发现小程序身份认证bug和新闻列表获取bug2.修改新增页面风格 轻 90% xyq 1.修改 ...
- BUAA软件工程个人作业-软件案例分析
BUAA个人博客作业-软件案例分析 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 软件案例分析 我在这个课程的目标是 学习开发软件的能力 这个作 ...
- C++的指针使用心得
使用C++有一段时间了,C++的手动内存管理缺失很麻烦,一不小心容易产生内存泄漏.自己总结了一点使用原则(不一定对),备注一下,避免忘记. 1.类外部传来的指针不处理 2.Qt对象管理的内存不处理 3 ...
- Django项目部署到阿里云服务器无法发送邮件,发送邮件超时问题解决
前言 今天, 博主将写了好久的一个Django小项目尝试在阿里云部署上线,由于项目中需要发送邮件,博主调用了163邮箱接口,在本地测试邮件功能正常,可是上线后,邮件功能一直超时崩溃.在百度一番查资料后 ...