小科技之卷积解决字符串匹配问题

1|0小科技之卷积解决字符串匹配问题

OI中有各种字符串匹配问题,常见的有单模式串匹配、多模式串匹配和子串匹配等,一般可以用KMP、AC自动机、SAM解决。如果涉及到其他形式的单模式串匹配,这些传统的方式很不好解决,有没有更灵活的处理方法或者通法呢?

答案是有的,而且就是耳熟能详的FFT/NTT。

我们先考虑最基础的单模式串匹配,求长为m的字符串T在长为n的字符串S里出现了多少次,只不过我们要用卷积来实现。具体的,我们设C(i,j)表示(sitj),即这两位是否相等,相等就为0,如果匹配了,那么自然有i=0m1C(xm+i+1,i)=0,但是这样有反例,例如abba都可以和ab匹配,因此我们改成i=0m1|C(xm+i+1,i)|=0才行。但是我们维护这个也是O(m)的,所以我们考虑给这一项平方,再设ans(x)=i=0m1C(xm+i+1,i)2=i=0m1(sxm+i+1ti)2,我们暴力拆柿子,得:

ans(x)=i=0m1sxm+i+122×sxm+i+1×ti+ti2=i=0m1sxm+i+12+i=1mti2i=0m12×sxm+i+1×ti

这时前两项可以预处理后O(1)算,问题就在于怎么求最后一项。我们发现这个形式不好看,于是我们把T翻转,即ti变成tmi1,那么就变成了

i=0m12×sxm+i+1×tmi1

注意到xm+i+1+mi1=x,那么这显然就是一个卷积式,我们可以O(nlogn)求出每一项,这样就可以O(nlogn)求出ans(x)了。

从这个算法得到启发,我们来总结做题的方法。

第一步:设计通配函数,即上文中的C(i,j)

第二步:设计完全通配函数,即上文中的ans(x)

第三步:计算每一位的完全通配函数的值。

来看几道简单的例题叭

1.P4173 残缺的字符串

题意:带通配符的单模式串匹配。

思路:因为有通配符的存在,所以我们设计C(i,j)=sitj(sitj)2,为什么要这样设计呢?因为对应位置相等的情况要么就是si=tj,要么就是si=||tj=,因此我们把通配符当成0,这样设计匹配函数就可以满足上面的条件了。

显然,完全通配函数就是

ans(x)=i=0m1sxm+i+1ti(sxm+i+1ti)2=i=0m1(sxm+i+13ti2sxm+i+12ti2+sxm+i+1ti3)

如何快速计算呢?我们把b翻转,就可以得到

ans(x)=i=0m1(sxm+i+13tmi12sxm+i+12tmi12+sxm+i+1tmi13)

这个形式就和卷积一样了,我们只需把s3t卷起来,再把s2t2卷起来,最后把st3卷起来就可以了。复杂度O(nlogn)

2.CF528D Fuzzy Search

题意:定义两个字符串匹配当且仅当T中每一个字符可以在S中找到一个相距不超过k的相同字符,求T在S中出现次数,字符集大小为4。

思路:这一题乍一看不好直接设计通配函数,我们发现这一题的字符集大小只有4,于是尝试对每一位分开计算。具体的当处理到字符ch时,我们把和ch相同的当成1,其他的是0,然后对S串正反扫一遍把所有与1相距不超过k的位置也标成1,这时两位匹配当且仅当ti=0ti=si=1,这样我们设计匹配函数C(i,j)=tj(aitj)2就满足条件了。

显然,完全匹配函数就是

ans(x)=i=0m1ti(sxm+i+1ti)2=i=0m1sxm+i+12ti2sxm+i+1ti2+ti3

根据我们的定义,fi,gi为0或1,那fik=fi,gik=gi,于是就把原式化简为

ans(x)=i=0m1sxm+i+1ti2sxm+i+1ti+ti=i=0m1tisxm+i+1ti

同样的,把T翻转,那么

ans(x)=i=0m1tii=0m1sxm+i+1tmi1

这样就可以卷积了。复杂度O(nlogn)

3.P3763 [TJOI2017]DNA

题意:求有多少个S的子串满足修改小于等于3个位置能够变成T,字符集大小为4。

思路:看到字符集大小很小,就想到对每一种字符单独考虑。S、T中和字符c相等的位置为1,定义匹配函数为C(i,j)=si×tj,那自然C(i,j)=1sitj匹配。

这时完全匹配函数就呼之欲出了。

ans(x)=i=0m1sxm+i+1ti

如果ans(x)+3m就合法

显然,计算时将T翻转 (是不是很套路?) ,得:

ans(x)=i=1m1sxm+i+1tmi1

这样就可以愉快地卷积了。复杂度O(nlogn)


__EOF__

本文作者Xttttr
本文链接https://www.cnblogs.com/Xttttr/p/17207151.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Xttttr  阅读(152)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示