Codeforces round 146 C - Cyclical Quest(后缀自动机)

本文介绍如何使用后缀自动机构建解决方案,解决Codeforces 146C题目中关于母串与多个子串的同构串匹配问题,通过复制子串并标记已匹配节点来准确计算所有不同同构串在母串中的出现次数。
Codeforces round 146 C - Cyclical Quest

题意:给出一个字符串s,这里我称之为母串,然后再给出n个子串,n<=10^5,子串长度总和不超过10^6。问,对于每一个子串的所有不同的同构串在母串中出现的次数总和。

解题思路:拿到这题,第一想法就是后缀自动机。。做法是这样的,先给母串建sam,为了解决同构问题,我们将读进来的子串复制一遍,除去最后一个字符。然后拿复制好的字串去自动机上跑,要记录的是当前能匹配的最长长度是多少,如果能匹配的长度大于等原子串长度,那么是能在母串中找到这个同构串的,那么怎么找出个数呢?很简单,其实就是匹配的当前节点的right集合的大小。为什么呢?因为每个节点都代表一个不一样的子串嘛。。但是这样还是不正确的,因为我当前走到的节点也许并不是最接近的,所以我们要沿着fa边走,直到fa的val小于原子串的长度,这时找到的节点的|right|才是真正的出现次数。然后还有一个问题就是有可能同构串相同,比如aa,那么它的同构串是aa,aa所以我们匹配到某一个节点时要把这个节点mark掉,下一次如果又走到这个mark节点,那么就不统计了。最后记得把mark清零。

代码:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值