BZOJ#4503. 两个串

Problem:

给定一个文本串(只包含a,b)和一个匹配串,匹配串中会有通用符(与任意字符都匹配),问文本串中有多少和匹配串相同的子串
Solution:
先看没有通用符怎么判断匹配
怎么判断一个字符匹配?
它们相等就匹配
怎么判断一个字符串匹配?
它们中每个对应的字符匹配就匹配
那么在这里可得一个式子:
Σ(a[i]-b[i])=0
可是会出现前面与后面刚好相加为0的情况
那么再改进一下:
Σ[(a[i]-b[i])^2]=0

如果有通用符怎么办?
Σ[b[i]*(a[i]-b[i])^2]=0 (b为匹配串,赋通用符为0,那么如果它为通用符,或者和a相等就匹配)

再化解一下式子:
ans=Σb[i]*(a[i]*a[i]-2*a[i]*b[i]+b[i]*b[i]
=Σa[i]*a[i]*b[i]-Σ2*a[i]*b[i]*b[i]+Σb[i]*b[i]*b[i]

式子解决了,我们怎么求?
看这个形式,如果我们把b反一下
我们就可以用卷积求得

可能没想清楚的同学会问,怎么保证卷积算出来的刚好就是一段连续的len2长度的子串
那么可以想一下,举个例子:
a=0 1 2 3 4 5 /b=0 1 2
当正在找以5为结尾的子串时
我们的卷积算的是Σa[i]+b[j](i+j==5)
我们b的j只会有0,1,2
那么我们的a只会选到相加等于5的编号的值,也就是5,4,3
可以看到我们刚好就是选到这个子串

ok!

猜你喜欢

转载自www.cnblogs.com/Heey/p/9058204.html