洛谷 P2375 [NOI2014] 动物园(kmp理解题)

博客讨论了字符串处理中的一个特定问题,即找出字符串中既是后缀也是前缀但不重叠的子串数量。通过分析KMP算法的next数组和fail数组,提出了两种不同的解决方案。第一种方法使用动态规划,但只适用于小数据规模;第二种方法优化为线性时间复杂度,成功解决了大输入限制。文章还给出了两种不同实现的C++代码,分别得到80分和100分的评测结果。

题目

bzoj3670

对于字符串S的前i个字符构成的子串,

既是它的后缀同时又是它的前缀,并且该后缀与该前缀不重叠,将这种字符串的数量记作num[i]

例如S为aaaaa,则num[4] = 2。

这是因为S的前4个字符为aaaa,其中a和aa都满足性质‘既是后缀又是前缀’,

同时保证这个后缀与这个前缀不重叠。

而aaa虽然满足性质‘既是后缀又是前缀’,

但遗憾的是这个后缀与这个前缀重叠了,所以不能计算在内。

同理,num[1] = 0,num[2] = num[3] = 1,num[5] = 2。

给定n(n<=5)组样例,每次给出一个长为l(l<=1e6)的小写字母串,

求所有(num[i]+1)的乘积,答案对1e9+7取模

思路来源

https://www.luogu.com.cn/blog/dedicatus545/solution-p2375

题解

仔细推根据kmp新构造的num的定义发现,

i的贡献dp[i],即为,从i跳next数组,即next[i],next[next[i]]连跳,

跳到第一个<=i/2的位置后开始计数,继续跳next数组,跳到位置为0的总次数

于是一个比较自然的想法是,倍增一下,然后处理出第一次跳到<=i/2的位置和跳到0的位置

但是只能过l<=5e5的小数据,只有80分,yyb换了两维就100分了很迷惑

于是考虑O(n)做法,利用了fail数组的性质,

 考虑在计算fail数组时,从i到i+1多了一个字母,而fail[i+1]一开始是在j=fail[i]的基础上回跳的,

(可以认为是,类似AC自动机的,ne

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值