当前位置: 首页 > news >正文

题解:洛谷 P8368([LNOI2022] 串)

1. Description

给定一个字符串 S,要求求出一个字符串序列 \(\{T_i\}\),满足 \(T_0\) 是 S 的子串,且对于 \(i\ne 0\)\(|T_i|=|T_{i-1}|+1\),且 \(S\) 存在一个子串 \(S^\prime\) 满足 \(S^\prime\) 长度为 \(|T_{i-1}|\) 的前缀为 \(T_{i-1}\),长度为 \(|T_i|\) 的后缀为 \(T_{i-1}\),求合法序列的最长长度。

2. Solution

感觉是一道不算很难的黑,难度有虚高嫌疑(?)。
一个结论是最优的序列一定是以空串开头的,这结论很显然,不过多赘述。
首先我们对限制条件进行一定的分析,方便我们写题。对于 \(T_i\)\(T_{i-1}\),因为 \(S^\prime\) 的长度为 \(|T_i|+1\),所以长度为 \(|T_{i-1}|\) 的前缀和长度为 \(|T_i|\) 的后缀将共用 \([2,|T_{i-1}|]\) 的部分。
由此,我们可以想到倒着构造,对于 \(T_i=S[l,r]\)\(T_{i-1}=S[l-1,r-2]\) 必然是一个合法的构造,此时 \(S^\prime=S[l-1,r]\)
那么答案的下限就是 \(\lfloor\frac{n}{2}\rfloor\),当初始的 \(r=n,l=\lfloor\frac{n}{2}\rfloor\) 时取到。
然后我们就需要考虑怎么增加这个答案,应该不难想到考虑一个子串在 \(S\) 中重复出现的情况,此时我们可以增加答案。
如何构造?我们假设 \(S[l_1,r_1]=S[l_2,r_2]\ (l_1<l_2)\),如果 \(r_1\)\(n\) 奇偶性相同,那么从 \([l_1+\frac{n-r_1}{2},n]\) 开始,一直平移,显然可以到达 \([l_1,r_1]\),此时将这个区间视作 \([l_2,r_2]\),继续进行平移,如此重复,每一次左端点平移到 \(l_1\),就跳回到 \(l_2\),直到区间长度为 \(0\) 为止,如果 \(r_i\)\(n\) 奇偶性不同,那么从 \([l_1+\frac{n-r_1-1}{2},n-1]\) 开始即可。
这样答案就是 \(\frac{n-r_1}{2}+r_1-l_1+1\),略微变换则有 \(\frac{n+r_1-l_1-l1+2}{2}\),也就是 \(\frac{n+len-l_1}{2}\)
考虑使用后缀数组求解,这个式子的最值必然由两个排名上相邻的后缀取得,理由是,如果 \(S[l_1,n],S[l_2,n]\) 在排名上不相邻,那么必然存在一个与 \(S[l_1,n]\) 在排名上相邻的后缀 \(S[x,n]\),使得 \(\operatorname{LCP}(S[l_1,n],S[l_2,n])\le \operatorname{LCP}(S[l_1,n],S[x,n]),\min(x,l_1)\le l_1\),得到的值显然更大。
那么代码的实现也就很简单了。

3. Code

/*by ChenMuJiu*/
/*略去缺省源与快读快写*/
const int N=5e5+5;
int n,ans;
int sa[N],rk[N],tmpsa[N],tmprk[N],cnt[N],f[N];
char s[N]; 
void init(int n){for(int i=1;i<=128;i++)cnt[i]=0;for(int i=1;i<=n;i++)cnt[s[i]]++;for(int i=1;i<=128;i++)cnt[i]+=cnt[i-1];for(int i=1;i<=n;i++)sa[cnt[s[i]]--]=i;for(int i=1,p=0;i<=n;i++){if(s[sa[i]]!=s[sa[i-1]])p++;rk[sa[i]]=p;}for(int k=1,now;k<n;k<<=1){now=0;for(int i=n-k+1;i<=n;i++)tmpsa[++now]=i;for(int i=1;i<=n;i++)cnt[i]=0;for(int i=1;i<=n;i++){cnt[rk[i]]++;if(sa[i]>k)tmpsa[++now]=sa[i]-k;}for(int i=1;i<=n;i++)cnt[i]+=cnt[i-1];for(int i=n;i>=1;i--)sa[cnt[rk[tmpsa[i]]]--]=tmpsa[i];for(int i=1;i<=n;i++)tmprk[i]=rk[i];for(int i=1,p=0;i<=n;i++){if(tmprk[sa[i]]==tmprk[sa[i-1]]&&tmprk[sa[i]+k]==tmprk[sa[i-1]+k])rk[sa[i]]=p;else rk[sa[i]]=++p;}}s[n+1]='#';for(int i=1,k=0,pos;i<=n;i++){if(rk[i]==1)continue;if(k)k--;pos=sa[rk[i]-1];while(s[i+k]==s[pos+k])k++;f[rk[i]]=k;}
}
signed main(){int t;read(t);while(t--){scanf("%s",s+1);n=strlen(s+1);init(n);ans=n/2;for(int i=2,len,l;i<=n;i++){len=f[i],l=min(sa[i-1],sa[i]);tomax(ans,(n+len-l+1)/2);}write(ans),Nxt;}
}
http://www.jsqmd.com/news/183417/

相关文章:

  • 神经符号方法在数学问题分解推理中的应用
  • ubuntu22.04(ROS2 humble)小车仿真环境搭建
  • 干货:AI应用架构师总结品牌价值量化的5个经典算法,附实现代码
  • 法院庭审前用Sonic模拟证人陈述过程进行预演
  • 哲学思辨录音:学者用VoxCPM-1.5-TTS-WEB-UI探讨意识本质问题
  • 2005:我在硅谷种AI-第2集:垃圾邮件的朴素审判
  • 记录一次糟糕的面试
  • 多语言扩展可能:Sonic未来是否会支持英语及其他语种?
  • 还在熬夜改论文?9款免费AI工具轻松搞定,科研党必备!
  • 叙事性技术传播:以《垃圾邮件的朴素审判》为例看故事如何拓宽技术教育的知识海洋【学术研究】
  • 2017:我为AI点亮火种-第3集:交锋!8GB显存之辩
  • [Unity 杂货铺] 引擎版本的选择
  • 图书馆借阅提示:逾期未还书籍由VoxCPM-1.5-TTS-WEB-UI发送催还通知
  • matlab代码:考虑天气因素的城市负荷预测
  • MATH Day 01 Applicaitons Practice
  • Sonic数字人防伪标识研究:如何辨别AI生成内容?
  • 什么是IGMP
  • Solana高速网络支撑Sonic实时生成交易提醒视频
  • 未来版本将加入水印标识防止滥用
  • 什么是IGMP Snooping
  • python闭包
  • JRebel 深度科普:为什么它能热加载新类,却改不动一个小小的 URL?
  • 什么是工业物联网(IIoT)
  • 老挝琅勃拉邦清晨:僧侣化缘时的脚步与低语
  • 电梯运行状态:故障停运时自动播放VoxCPM-1.5-TTS-WEB-UI紧急通知
  • 我的世界服务器motd查询
  • 互联网大厂Java面试:从基础到应用的全面考察
  • AI数字人新突破:Sonic实现自然表情与唇形同步生成
  • 什么是iNOF
  • 详细介绍:软件工程领域用户运营的用户运营案例深度剖析