洛谷P1117 [NOI2016] 优秀的拆分 题解(代码很长,请耐心)

本文介绍了如何利用后缀自动机来解决NOI2016中关于优秀拆分的问题。通过计算以特定位置开始和结束的AA串数量,来找出所有可能的AA串接点,并用差分方法更新f和g数组,最终求得答案。文章详细阐述了算法思路,并提到了后缀数组作为替代方案,同时提供了相应的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看了一圈题解没有后缀自动机的题解,不过毕竟后缀自动机后缀数组一家人,这里和大家分享后缀自动机的做法。

思路是一样的,处理出有多少个AA串以i开头,记做f[i],有多少个AA串以i结尾,记做g[i],那么ans就是所有的g[i]f[i+1]

以下用pre(i)表示以i结尾的前缀,suffix(i)表示以i开头的后缀。

怎么去求g与f数组呢,考虑AA的拼接,设它的接点是第二个A开始的位置。设一个A的长度为L,那么对于一个长度为L的区间[i,j]来说,设pre(i-1)与pre(j-1)的最长公共后缀长度为x suffix(i)与suffix(j)的最长公共前缀长度为y,那么[j-x,i+y+1]都能作为接点(注意[i-x,i+y-1] 与 [j-x,j+y-1]是相同的子串

为了不统计重,区间[i,j]只统计接点在[i,j]范围内的AA串,所以x与L取min,y与L-1取min。

现在问题的步骤便出来了: 1.枚举一个A的长度L。

2.枚举i=KL,j=i+L,统计接点在区间[i,j]中的AA串对于f与g的贡献:

3.查询x与y,定义如上所示。

4.如果x+y<L,接不上,没有贡献。

5.否则每个[i-x,i-x+(x+y-L)]区间内的点都能作为AA串的左端点,当然,其右端点为[j+y-1-(x+y-L),j+y-1],建议画图理解。发现每个区间对于f与g的贡献相当于一个区间加1,所以差分点修改。

6.最后统计前缀和即可求出f与g数组。ans=所有g[i]f[i+1]

那么问题的关键是:怎么求前缀的最长公共后缀?后缀数组可以,当

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值