题目大意
给出两个字符串
A
A
A 和
B
B
B,长度分别为
n
n
n 和
m
m
m,其中包含
′
∗
′
'*'
′∗′ 字符,它可以匹配任意 1个 字符,求
A
A
A 串在
B
B
B 串中的出现次数。
数据范围
1
⩽
m
⩽
n
⩽
300000
1\leqslant m\leqslant n\leqslant 300000
1⩽m⩽n⩽300000
题解
为了方便叙述,定义
S
i
.
.
j
S_{i..j}
Si..j 表示由S的第
i
i
i 个字符开始到第
j
j
j 个字符组成的字符串。
设
′
∗
′
=
0
'*' =0
′∗′=0,定义两个字符串之间的距离为:
d
i
s
(
S
,
T
)
=
∑
(
S
i
−
T
i
)
2
S
i
T
i
dis(S,T)=\sum (S_i-T_i)^2S_iT_i
dis(S,T)=∑(Si−Ti)2SiTi
可以发现,当且仅当
d
i
s
(
S
,
T
)
=
0
dis(S,T)=0
dis(S,T)=0 时,
S
S
S 和
T
T
T 匹配。
接下来暴力一些,定义
f
[
i
]
=
d
i
s
(
A
0..
(
m
−
1
)
,
B
(
i
−
m
+
1
)
.
.
i
)
f[i]=dis(A_{0..(m-1)},B_{(i-m+1)..i})
f[i]=dis(A0..(m−1),B(i−m+1)..i),如果我们求出了
f
f
f 数组,那问题就变成了
f
f
f 数组中有多少个
0
0
0。
f
[
i
]
=
∑
j
=
0
m
−
1
(
A
[
j
]
−
B
[
i
−
m
+
1
+
j
]
)
2
A
[
j
]
B
[
i
−
m
+
1
+
j
]
f[i]=\sum_{j=0}^{m-1}\limits(A[j]-B[i-m+1+j])^2A[j]B[i-m+1+j]
f[i]=j=0∑m−1(A[j]−B[i−m+1+j])2A[j]B[i−m+1+j]
将A串翻转,得:
f
[
i
]
=
∑
j
=
0
m
−
1
(
A
[
m
−
j
−
1
]
−
B
[
i
−
m
+
1
+
j
]
)
2
A
[
m
−
j
−
1
]
B
[
i
−
m
+
1
+
j
]
f[i]=\sum_{j=0}^{m-1}\limits(A[m-j-1]-B[i-m+1+j])^2A[m-j-1]B[i-m+1+j]
f[i]=j=0∑m−1(A[m−j−1]−B[i−m+1+j])2A[m−j−1]B[i−m+1+j]
拆开得到:
f
[
i
]
=
∑
j
=
0
m
−
1
A
[
m
−
j
−
1
]
3
B
[
i
−
m
+
1
+
j
]
−
2
∗
∑
j
=
0
m
−
1
A
[
m
−
j
−
1
]
2
B
[
i
−
m
+
1
+
j
]
2
+
∑
j
=
0
m
−
1
B
[
i
−
m
+
1
+
j
]
3
∗
A
[
m
−
j
−
1
]
f[i]=\quad\ \sum_{j=0}^{m-1}\limits A[m-j-1]^3B[i-m+1+j]\\ \quad\qquad-2*\sum_{j=0}^{m-1}\limits A[m-j-1]^2B[i-m+1+j]^2\\ \quad\qquad+\sum_{j=0}^{m-1}\limits B[i-m+1+j]^3*A[m-j-1]
f[i]= j=0∑m−1A[m−j−1]3B[i−m+1+j]−2∗j=0∑m−1A[m−j−1]2B[i−m+1+j]2+j=0∑m−1B[i−m+1+j]3∗A[m−j−1]
定义
f
a
[
i
]
=
∑
j
=
0
m
−
1
A
[
m
−
j
−
1
]
3
B
[
i
−
m
+
1
+
j
]
fa[i]=\sum_{j=0}^{m-1}\limits A[m-j-1]^3B[i-m+1+j]
fa[i]=j=0∑m−1A[m−j−1]3B[i−m+1+j]
f b [ i ] = ∑ j = 0 m − 1 A [ m − j − 1 ] 2 B [ i − m + 1 + j ] 2 fb[i]=\sum_{j=0}^{m-1}\limits A[m-j-1]^2B[i-m+1+j]^2 fb[i]=j=0∑m−1A[m−j−1]2B[i−m+1+j]2
f
c
[
i
]
=
∑
j
=
0
m
−
1
A
[
m
−
j
−
1
]
B
[
i
−
m
+
1
+
j
]
3
fc[i]=\sum_{j=0}^{m-1}\limits A[m-j-1]B[i-m+1+j]^3
fc[i]=j=0∑m−1A[m−j−1]B[i−m+1+j]3
则:
f
[
i
]
=
f
a
[
i
]
+
2
∗
f
b
[
i
]
+
f
c
[
i
]
f[i]=fa[i]+2*fb[i]+fc[i]
f[i]=fa[i]+2∗fb[i]+fc[i]
然后
f
a
fa
fa,
f
b
fb
fb 和
f
c
fc
fc 用FFT计算即可。