FMT與子集卷積
FMT與子集卷積
求 C x = ∑ i ⋃ j = x a i ∗ b j C_x = \sum_{i\bigcup j = x}a_i*b_j Cx=∑i⋃j=xai∗bj
sol.
構造一個
F
M
T
(
A
)
=
∑
i
⊂
x
a
i
FMT(A) = \sum_{i\subset x}a_i
FMT(A)=∑i⊂xai
F
M
T
x
(
A
)
∗
F
M
T
x
(
B
)
=
∑
k
⊂
x
∑
i
⋃
j
=
k
a
i
∗
b
j
=
∑
k
⊂
x
C
k
=
F
M
T
x
(
C
)
FMT_x(A) * FMT_x(B) = \sum_{k \subset x}\sum_{i \bigcup j = k}a_i*b_j\\ =\sum_{k \subset x}C_k\\ = FMT_x(C)
考慮如何快速構造這個 F M T ( A ) FMT(A) FMT(A)
很顯然的一個事情 F M T ( A ) = F M T ( A 0 ) + F M T ( A 1 ) [ 用 二 進 制 表 示 集 合 , 分 別 有 沒 由 前 面 的 第 一 個 元 素 ] FMT(A) = FMT(A_0) + FMT(A1) [用二進位制表示集合,分別有沒由前面的第一個元素] FMT(A)=FMT(A0)+FMT(A1)[用二進制表示集合,分別有沒由前面的第一個元素]
那麼可以直接二進位制倍增來寫。。。
for(int len = 2 ; len <= n ; len = (len << 1)){
for(int i = 0 ; i <= n ; i = i + len){
for(int j = 0 ; j < (len >> 1) ; j++){
f[i + j + (len >> 1)] += f[i + j];
}
}
}
大概就像這樣就可以了
逆FMT的話如下
for(int len = 2 ; len <= n ; len = (len << 1)){ for(int i = 0 ; i <= n ; i = i + len){ for(int j = 0 ; j < (len >> 1) ; j++){ f[i + j] -= f[i + j + (len >> 1)]; } } }
就可以做掉了。。。。
FWT是這個玩意的加強版,專門來處理二進位制操作卷積的
o r or or卷積,就是上面的FMT
a n d and and卷積:
需要構造一個 F M T ( A ) FMT(A) FMT(A)使得, F W T ( A ) x ∗ F W T ( B ) x = F W T ( C ) x FWT(A)_x * FWT(B)_x = FWT(C)_x FWT(A)x∗FWT(B)x=FWT(C)x
即:
∑
i
&
x
=
x
a
i
∗
∑
j
&
x
=
x
b
j
=
∑
(
i
&
j
)
&
x
=
x
a
i
∗
b
j
=
∑
i
&
x
=
x
c
i
\sum_{i \& x = x}a_i* \sum _ {j \& x = x}b_j = \sum_{(i \& j) \& x = x}a_i * b_j = \sum_{i \& x = x}c_i
i&x=x∑ai∗j&x=x∑bj=(i&j)&x=x∑ai∗bj=i&x=x∑ci
所以需要構造出:
F
W
T
x
(
A
)
=
∑
i
&
x
=
x
a
i
FWT_x(A) = \sum_{i \& x = x}a_i
FWTx(A)=i&x=x∑ai
大概就是這樣
for(int len = 2 ; len <= n ; len = (len << 1)){
for(int i = 0 ; i <= n ; i = i + len){
for(int j = 0 ; j < (len >> 1) ; j++){
f[i + j] = f[i + j] + f[i + j + (len >> 1)];
}
}
}
xor卷積:
需要構造一個 F M T ( A ) FMT(A) FMT(A)使得, F W T ( A ) x ∗ F W T ( B ) x = F W T ( C ) x FWT(A)_x * FWT(B)_x = FWT(C)_x FWT(A)x∗FWT(B)x=FWT(C)x
即
∑
i
x
o
r
x
=
x
a
i
∑
j
x
o
r
x
=
x
b
j
=
\sum_{i \ xor\ x\ =\ x}a_i \sum_{j \ xor \ x \ = \ x}b_j =
ixorx=x∑aijxorx=x∑bj=
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-Vgia3cKl-1613121592741)(C:\Users\Administrator\Desktop\筆記\FWT2.PNG)]
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-5jsO5avm-1613121592758)(C:\Users\Administrator\Desktop\筆記\FWT3.PNG)]
補一個證明
g
(
x
,
j
)
∗
g
(
x
,
k
)
=
(
−
1
)
∣
j
⋂
x
∣
+
∣
k
⋂
x
∣
=
(
−
1
)
(
j
x
o
r
k
)
⋂
x
g(x,j) * g(x , k) = (-1)^{|j\bigcap x| + |k\bigcap x|} = (-1)^{(j \ xor \ k) \bigcap x}
g(x,j)∗g(x,k)=(−1)∣j⋂x∣+∣k⋂x∣=(−1)(jxork)⋂x
很顯然的東西吖。。。。
所以就有程式碼
for(int len = 2 ; len <= n ; len = (len << 1)){
for(int i = 0 ; i <= n ; i += len){
for(int j = 0 ; j < (len << 1) ; j++){
int A = f[i + j] , B = f[i + j + k];
f[i + j] = A + B;
f[i + j + k] = A - B;
}
}
}
很顯然的吧
逆的話,程式碼如下
for(int len = 2 ; len <= n ; len = (len << 1)){
for(int i = 0 ; i <= n ; i += len){
for(int j = 0 ; j < (len << 1) ; j++){
int A = f[i + j] , B = f[i + j + k];
f[i + j] = (A + B) / 2;
f[i + j + k] = (A - B) / 2;
}
}
}
FWT可以用來做一些高維字首和的問題
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ibOaQY33-1613121592772)(C:\Users\Administrator\Desktop\筆記\FWT4.PNG)]
很顯然就是 A L L = ∑ ( − 1 ) ∣ 與 n o w 相 關 的 維 度 ∣ a n o w ALL = \sum (-1)^{|與now相關的維度|}a_{now} ALL=∑(−1)∣與now相關的維度∣anow
與上面異或的定義 g ( x , i ) g(x,i) g(x,i)非常的相似(實際上就是同一個玩意)
實際上就是一個xor卷積的事情。。。。
入門題:luoguP3175 [HAOI2015]按位或
很容易列出方程
f
[
i
]
=
∑
j
∑
(
k
∣
j
)
=
i
(
f
[
k
]
+
1
)
∗
p
[
j
]
f
[
i
]
=
∑
j
!
=
i
∑
(
k
∣
j
)
=
i
(
f
[
k
]
+
1
)
∗
p
[
j
]
+
∑
k
∣
i
=
i
(
f
[
i
]
+
1
)
∗
p
[
k
]
f
[
i
]
=
∑
j
!
=
i
∑
(
k
∣
j
)
=
i
(
f
[
k
]
+
1
)
∗
p
[
j
]
+
∑
k
∣
i
=
i
p
[
k
]
1
−
∑
k
∣
i
=
i
p
[
k
]
f[i] = \sum_{j}\sum_{(k|j) \ =\ i}(f[k] + 1) * p[j]\\ f[i] = \sum_{j != i}\sum_{(k|j) \ =\ i}(f[k] + 1) * p[j] + \sum_{k | i\ =\ i}(f[i] + 1) * p[k]\\ f[i] = \frac {\sum_{j != i}\sum_{(k|j) \ =\ i}(f[k] + 1) * p[j] + \sum_{k | i\ =\ i}p[k]} {1 - \sum_{k | i\ =\ i}p[k]}
f[i]=j∑(k∣j)=i∑(f[k]+1)∗p[j]f[i]=j!=i∑(k∣j)=i∑(f[k]+1)∗p[j]+k∣i=i∑(f[i]+1)∗p[k]f[i]=1−∑k∣i=ip[k]∑j!=i∑(k∣j)=i(f[k]+1)∗p[j]+∑k∣i=ip[k]
s
o
l
1.
解
決
分
母
的
快
速
計
算
,
直
接
對
{
p
}
做
一
個
f
w
t
就
好
了
,
s
o
l
2.
分
子
第
二
項
同
s
o
l
1.
s
o
l
3.
分
子
第
一
項
最
爛
每
一
次
都
要
做
一
個
F
W
T
O
(
2
n
∗
2
n
∗
n
)
sol1.解決分母的快速計算,直接對\{p\}做一個fwt就好了,\\ sol2.分子第二項同sol1.\\ sol3.分子第一項最爛每一次都要做一個FWT\\ O(2^n * 2 ^ n * n)
sol1.解決分母的快速計算,直接對{p}做一個fwt就好了,sol2.分子第二項同sol1.sol3.分子第一項最爛每一次都要做一個FWTO(2n∗2n∗n)
很顯然是不行的吧。。。
本人只能想到這種。。。
如果能做到動態維護 FWT卷積的話,這個式子還是很好做的。。。
。。。。
正解是 min-max容斥。。。。
我先去補一下二項式反演的坑
就好了,\
sol2.分子第二項同sol1.\
sol3.分子第一項最爛每一次都要做一個FWT\
O(2^n * 2 ^ n * n)
$$
很顯然是不行的吧。。。
本人只能想到這種。。。
如果能做到動態維護 FWT卷積的話,這個式子還是很好做的。。。
。。。。
正解是 min-max容斥。。。。
我先去補一下二項式反演的坑