整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


目录

  • 0x00 卷积
    • 0x01 多项式
    • 0x02 卷积的定义
    • 0x03 卷积的基本性质
    • 0x04 位运算卷积定义及其性质
  • 0x10 FWT(快速沃尔什变换)
    • 0x11 或(or\text{or}or)卷积
    • 0x12 与(and\text{and}and)卷积
    • 0x13 异或(xor\text{xor}xor)卷积
    • 0x14 模板
  • 0x20 FMT与FMI(快速莫比乌斯变换与快速莫比乌斯反演)
  • 0x30 竞赛例题选讲
    • A、(牛客练习赛41 F)简单数学题
    • B、(2018 ACM - ICPC shenyang I)Distance Between Sweethearts
    • C、(2019ACM - ICPC nanchang H)Another Sequence
    • D、(CROC 2016 - Final Round C)Binary Table
    • E、(HAOI2015)luogu P3175 按位或

前置知识:FFT

开始的开始,我们先来复习一下卷积的相关概念(注:0x00 卷积的部分内容(0x02、0x03、0x04)摘自 @wangrx,他写的太好了 %%%,略作修改完善,侵删)之后本文中所有的符号也都参照他的形式书写。以及本文中所有的多项式的系数 nnn 均为 222 的整数幂的形式(学过 FFT 的都懂hhh不然就没法分治了)

自认为本文是最为清晰完整的 FWT 讲解博客,含有全套完整清晰的证明,相信小学生都能看懂 ~

前排规定本文所用符号:

多项式 / 序列卷积:⊗\otimes⊗

多项式 / 序列对应系数相乘 / 普通的乘法: ×\times×

多项式 / 序列第 kkk 项系数: (f)k(f)_k(f)k​ , (f⊗g)k(f\otimes g)_k(f⊗g)k​ ,(A)[k](A)[k](A)[k]

多项式 / 序列加法: ⊕\oplus⊕

多项式 / 序列减法: ⊖\ominus⊖

多项式 / 序列 or\text {or}or 卷积( |,或): ⊗or\otimes_{\text{or}}⊗or​

多项式 / 序列 and\text {and}and 卷积( &,或): ⊗and\otimes_{\text{and}}⊗and​

多项式 / 序列 xor\text {xor}xor 卷积( ^,或): ⊗xor\otimes_{\text{xor}}⊗xor​

0x00 卷积

0x01 多项式

我们知道对于一个普通的多项式可以表示为系数表示: f(x)=a0x0+a1x1+⋅⋅⋅+an−1xn−1f(x)=a_0x^0+a_1x^1+···+a_{n-1}x^{n-1}f(x)=a0​x0+a1​x1+⋅⋅⋅+an−1​xn−1

规定 f=a0x0+a1x1+⋅⋅⋅+an−1xn−1f=a_0x^0+a_1x^1+···+a_{n-1}x^{n-1}f=a0​x0+a1​x1+⋅⋅⋅+an−1​xn−1,g=b0x0+b1x1+⋅⋅⋅+bn−1xn−1g=b_0x^0+b_1x^1+···+b_{n-1}x^{n-1}g=b0​x0+b1​x1+⋅⋅⋅+bn−1​xn−1

则可将多项式的系数表示简化为: f=(a0,a1,a2⋅⋅⋅an−1)f=(a_0,a_1,a_2···a_{n-1})f=(a0​,a1​,a2​⋅⋅⋅an−1​),g=(b0,b1,b2⋅⋅⋅bn−1)g=(b_0,b_1,b_2···b_{n-1})g=(b0​,b1​,b2​⋅⋅⋅bn−1​)


定义多项式加减法:⊕,⊖\oplus,\ominus⊕,⊖
H=f⊕g=(a0,a1,a2⋅⋅⋅an−1)⊕(b0,b1,b2⋅⋅⋅bn−1)=(a0+b0,a1+b1,a2+b2⋅⋅⋅an−1+bn−1)\begin{aligned} H&=f\oplus g\\& =(a_0,a_1,a_2⋅⋅⋅a_{n−1})\oplus (b_0,b_1,b_2⋅⋅⋅b_{n−1})\\&=(a_0+b_0,a_1+b_1,a_2+b_2⋅⋅⋅a_{n−1}+b_{n−1}) \end{aligned} H​=f⊕g=(a0​,a1​,a2​⋅⋅⋅an−1​)⊕(b0​,b1​,b2​⋅⋅⋅bn−1​)=(a0​+b0​,a1​+b1​,a2​+b2​⋅⋅⋅an−1​+bn−1​)​

H=f⊖g=(a0,a1,a2⋅⋅⋅an−1)⊕(b0,b1,b2⋅⋅⋅bn−1)=(a0−b0,a1−b1,a2−b2⋅⋅⋅an−1−bn−1)\begin{aligned} H&=f\ominus g\\& =(a_0,a_1,a_2⋅⋅⋅a_{n−1})\oplus (b_0,b_1,b_2⋅⋅⋅b_{n−1})\\&=(a_0-b_0,a_1-b_1,a_2-b_2⋅⋅⋅a_{n−1}-b_{n−1}) \end{aligned} H​=f⊖g=(a0​,a1​,a2​⋅⋅⋅an−1​)⊕(b0​,b1​,b2​⋅⋅⋅bn−1​)=(a0​−b0​,a1​−b1​,a2​−b2​⋅⋅⋅an−1​−bn−1​)​

其中多项式加减的第 kkk 项系数:

(f⊕g)k=akfk+bkgk(f\oplus g)_k=a_kf_k+b_kg_k (f⊕g)k​=ak​fk​+bk​gk​

(f⊖g)k=akfk−bkgk(f\ominus g)_k=a_kf_k-b_kg_k (f⊖g)k​=ak​fk​−bk​gk​


定义多项式对应系数相乘一定注意这里不是卷积 ⊗\otimes⊗
H=f×g=(a0,a1,a2⋅⋅⋅an−1)×(b0,b1,b2⋅⋅⋅bn−1)=(a0×b0,a1×b1,a2×b2⋅⋅⋅an−1×bn−1)\begin{aligned} H&=f\times g\\& =(a_0,a_1,a_2⋅⋅⋅a_{n−1})\times (b_0,b_1,b_2⋅⋅⋅b_{n−1})\\&=(a_0\times b_0,a_1\times b_1,a_2\times b_2⋅⋅⋅a_{n−1}\times b_{n−1}) \end{aligned} H​=f×g=(a0​,a1​,a2​⋅⋅⋅an−1​)×(b0​,b1​,b2​⋅⋅⋅bn−1​)=(a0​×b0​,a1​×b1​,a2​×b2​⋅⋅⋅an−1​×bn−1​)​

其中多项式对应系数相乘的第 kkk 项系数:

(f⊗g)k=akfk×bkgk(f\otimes g)_k=a_kf_k\times b_kg_k (f⊗g)k​=ak​fk​×bk​gk​


0x02 卷积的定义

对于一个序列,将其中元素一一映射到一个多项式函数的系数上, 这个多项式函数便叫做该序列的生成函数

形式化地讲,对于序列 f0,f1,⋯,fn−1f_0,f_1,\cdots,f_{n-1}f0​,f1​,⋯,fn−1​ , F(x)=∑k=0n−1fkxkF(x)=\displaystyle\sum_{k=0}^{n-1}f_kx^kF(x)=k=0∑n−1​fk​xk 为其生成函数。

卷积即为生成函数的乘积在对应序列的变换上的的抽象,“卷”即为其作用效果,“积”即为其本质。

对于序列 f,gf,gf,g ,其卷积序列 f⊗gf\otimes gf⊗g 满足 (f⊗g)k=∑i=0kfi×gk−i=∑i,ji+j=kfi×gj(f\otimes g)_k=\displaystyle\sum\limits_{i=0}^kf_i\times g_{k-i}=\sum\limits_{i,j}^{i+j=k}f_i\times g_j(f⊗g)k​=i=0∑k​fi​×gk−i​=i,j∑i+j=k​fi​×gj​

对于多项式 f,gf,gf,g,其多项式的卷积为:f⊗g=∑k=0n(∑i,ji+j=kai×bj)xkf\otimes g=\sum\limits_{k=0}^{n}(\sum\limits_{i,j}^{i+j=k}a_i\times b_j)x^kf⊗g=k=0∑n​(i,j∑i+j=k​ai​×bj​)xk

而我们所熟知的 FFT 计算的是循环卷积,也即 (f⊗g)k=∑i+j≡k(modn)fi×gj(f\otimes g)_k=\displaystyle\sum_{i+j\equiv k\pmod n}f_i\times g_j(f⊗g)k​=i+j≡k(modn)∑​fi​×gj​ , nnn 为序列长度。

0x03 卷积的基本性质

这里的卷积均为序列的卷积,因此证明时我们使用数学归纳法,即证明第 kkk 项成立,则整个序列均成立。由于多项式实际上就是序列的生成函数,所以性质同样成立。

  • f⊗g=g⊗ff\otimes g=g\otimes ff⊗g=g⊗f(交换律)

    我们使用定义 (f⊗g)k=∑i+j=kfi×gj(f\otimes g)_k=\displaystyle\sum_{i+j=k}f_i\times g_j(f⊗g)k​=i+j=k∑​fi​×gj​ ,以及乘法交换律 a×b=b×aa\times b=b\times aa×b=b×a 即可证明,因为 i+j=ki+j=ki+j=k 的 iii 和 jjj 是一一对应的。

  • (f⊗g)⊗h=f⊗(g⊗h)(f\otimes g)\otimes h=f\otimes(g \otimes h)(f⊗g)⊗h=f⊗(g⊗h) (结合律)
    证明:
    [f⊗(g⊗h)]n=∑i=0nfn−i×(g⊗h)i=∑i=0nfn−i∑j=0igjhi−j=∑i=0n∑j=0ifn−igjhi−j=∑i+j+k=nfigjhk\begin{aligned} {[f\otimes(g\otimes h)]_n} & =\displaystyle\sum_{i=0}^nf_{n-i}\times(g\otimes h)_i & \\& =\sum_{i=0}^nf_{n-i}\sum_{j=0}^ig_jh_{i-j}\\& =\sum_{i=0}^n\sum_{j=0}^if_{n-i}g_jh_{i-j}\\& =\sum_{i+j+k=n}f_ig_jh_k\end{aligned} [f⊗(g⊗h)]n​​=i=0∑n​fn−i​×(g⊗h)i​=i=0∑n​fn−i​j=0∑i​gj​hi−j​=i=0∑n​j=0∑i​fn−i​gj​hi−j​=i+j+k=n∑​fi​gj​hk​​

交换顺序后反向推导即可得证。

  • (f⊕g)⊗h=(f⊗h)⊕(g⊗h)(f\oplus g)\otimes h=(f\otimes h)\oplus(g\otimes h)(f⊕g)⊗h=(f⊗h)⊕(g⊗h) (分配律)
    其中 (f⊕g)k=afk+bgk(f\oplus g)_k=af_k+bg_k(f⊕g)k​=afk​+bgk​ ,即序列 f,gf,gf,g 的加法, a,ba,ba,b 为常数。

证明:
[(f⊕g)⊗h]k=∑i=0k(f⊕g)ihk−i=∑i=0k(afi+bgi)hk−i=∑i=0k(afihk−i+bgihk−i)=a∑i=0kfihk−i+b∑i=0kgihk−i=a(f⊗h)k+b(g⊗h)k=[(f⊗h)⊕(g⊗h)]k\begin{aligned} {[(f\oplus g)\otimes h]_k} &=\displaystyle\sum_{i=0}^k(f\oplus g)_ih_{k-i}\\ & =\sum_{i=0}^k (af_i+bg_i)h_{k-i} \\ &=\sum_{i=0}^k(af_ih_{k-i}+bg_ih_{k-i})\\ &=a\sum_{i=0}^kf_ih_{k-i}+b\sum_{i=0}^kg_ih_{k-i}\\&=a(f\otimes h)_k+b(g\otimes h)_k=[(f\otimes h)\oplus(g\otimes h)]_k \end{aligned} [(f⊕g)⊗h]k​​=i=0∑k​(f⊕g)i​hk−i​=i=0∑k​(afi​+bgi​)hk−i​=i=0∑k​(afi​hk−i​+bgi​hk−i​)=ai=0∑k​fi​hk−i​+bi=0∑k​gi​hk−i​=a(f⊗h)k​+b(g⊗h)k​=[(f⊗h)⊕(g⊗h)]k​​

0x04 位运算卷积定义及其性质

一般的卷积满足 i+j=ki+j=ki+j=k ,又称为加法卷积。

类似的,对于序列 f={f0,f1,⋯,f2n−1},g={g0,g1,⋯,g2n−1}f=\{f_0,f_1,\cdots,f_{2^n-1}\},g=\{g_0,g_1,\cdots,g_{2^n-1}\}f={f0​,f1​,⋯,f2n−1​},g={g0​,g1​,⋯,g2n−1​} ,
可以定义位运算卷积 (f⊗⊙g)k=∑i⊙j=kfi×gj\displaystyle(f\otimes_\odot g)_k=\sum_{i\odot j=k}f_i\times g_j(f⊗⊙​g)k​=i⊙j=k∑​fi​×gj​ ,其中 ⊙=and,or,xor\odot=\text{and},\text{or},\text{xor}⊙=and,or,xor 。
还有 max⁡\maxmax 卷积,这里不再拓展, 读者自行查找相关资料,现在着重讨论 ⊗xor\otimes_\text{xor}⊗xor​

  • f⊗xorg=g⊗xor\displaystyle f\otimes_\text{xor} g=g\otimes_\text{xor}f⊗xor​g=g⊗xor​ (交换律)
    由于 axor⁡b=bxor⁡a\operatorname{xor}b=b\operatorname{xor}axorb=bxor ,根据定义显然成立。
    and⁡,or⁡and,or\operatorname{and},\operatorname{or}and,orand,orand,or 同样满足此性质,原因同上。
  • (f⊗xorg)⊗xorh=f⊗xor(g⊗xorh)(f\otimes_\text{xor} g)\otimes_\text{xor} h=f\otimes_\text{xor}(g \otimes_\text{xor} h)(f⊗xor​g)⊗xor​h=f⊗xor​(g⊗xor​h) (结合律)
    证明: 根据定义,有 (f⊗xorg)k=∑ixor⁡j=kfi×gj=∑i=02n−1fi×gkxor⁡i(f\otimes_\text{xor} g)_k=\displaystyle\sum_{i\operatorname{xor}j=k}f_i\times g_j=\sum\limits_{i=0}^{2^n-1}f_i\times g_{k\operatorname{xor}i}(f⊗xor​g)k​=ixorj=k∑​fi​×gj​=i=0∑2n−1​fi​×gkxori​ ,则

[f⊗xor(g⊗xorh)]m=∑i=02n−1fmxor⁡i×(g⊗xorh)i=∑i=02n−1fmxor⁡i∑j=02n−1gjhixor⁡j=∑i=02n−1∑j=02n−1fmxor⁡igjhixor⁡j=∑ixor⁡jxor⁡k=mfigjhk\begin{aligned} {[f\otimes_\text{xor}(g\otimes_\text{xor}h)]_m} & =\sum_{i=0}^{2^n-1}f_{m\operatorname{xor}i}\times(g\otimes_\text{xor}h)_i \\&=\sum_{i=0}^{2^n-1}f_{m\operatorname{xor}i}\sum_{j=0}^{2^n-1}g_jh_{i\operatorname{xor}j}\\&=\sum_{i=0}^{2^n-1}\sum_{j=0}^{2^n-1}f_{m\operatorname{xor}i}g_jh_{i\operatorname{xor}j}\\& =\sum_{i\operatorname{xor}j\operatorname{xor}k=m}f_ig_jh_k\end{aligned} [f⊗xor​(g⊗xor​h)]m​​=i=0∑2n−1​fmxori​×(g⊗xor​h)i​=i=0∑2n−1​fmxori​j=0∑2n−1​gj​hixorj​=i=0∑2n−1​j=0∑2n−1​fmxori​gj​hixorj​=ixorjxork=m∑​fi​gj​hk​​

交换顺序后反向推导即可得证。
or⁡,and⁡\operatorname{or},\operatorname{and}or,and 没有对应的逆运算,因此证明相对复杂,这里不给出证明。

  • (f⊕g)⊗xorh=(f⊗xorh)⊕(g⊗xorh)(f\oplus g)\otimes_\text{xor} h=(f\otimes_\text{xor} h)\oplus(g\otimes_\text{xor} h)(f⊕g)⊗xor​h=(f⊗xor​h)⊕(g⊗xor​h) (分配律)
    证明同加法卷积, and⁡,or⁡\operatorname{and},\operatorname{or}and,or 同理。

0x10 FWT(快速沃尔什变换)

复习完上述基本概念以后,我们进入今天的正题,快速沃尔什变换(FWT)。

我们知道 FFT 是用来在 O(nlogn)\mathcal O(nlogn)O(nlogn) 的时间复杂度下利用分治求解普通序列 / 多项式的卷积:

对于序列 f,gf,gf,g ,其卷积序列 f⊗gf\otimes gf⊗g 满足对于 f⊗gf\otimes gf⊗g 的第 kkk 项: (f⊗g)k=∑i=0kfi×gk−i=∑i,ji+j=kfi×gj(f\otimes g)_k=\displaystyle\sum\limits_{i=0}^kf_i\times g_{k-i}=\sum\limits_{i,j}^{i+j=k}f_i\times g_j(f⊗g)k​=i=0∑k​fi​×gk−i​=i,j∑i+j=k​fi​×gj​

对于多项式 f,gf,gf,g,其多项式的卷积为:f⊗g=∑k=0n(∑i,ji+j=kai×bj)xk\displaystyle f\otimes g=\sum\limits_{k=0}^{n}(\sum\limits_{i,j}^{i+j=k}a_i\times b_j)x^kf⊗g=k=0∑n​(i,j∑i+j=k​ai​×bj​)xk

上面定义了位运算卷积: (f⊗⊙g)k=∑i⊙j=kfi×gj\displaystyle(f\otimes_\odot g)_k=\sum_{i\odot j=k}f_i\times g_j(f⊗⊙​g)k​=i⊙j=k∑​fi​×gj​ ,其中 ⊙=and,or,xor\odot=\text{and},\text{or},\text{xor}⊙=and,or,xor ,并讲解了一系列相关性质,那么我们如何求得位运算卷积呢?我们模仿 FFT 给出一种类似的求解算法:快速沃尔什变换(FWT)。

严格来讲,FWT 仅为 xor\text {xor}xor 卷积,FMT 为 and\text{and}and、or\text{or}or 卷积,这里放到一块统称为 FWT。(Qwq)

首先我们先来回忆一下FFT是如何求解多项式卷积呢?

我们将两个 (n−1)(n - 1)(n−1) 次多项式 A(x)=∑i=0n−1aixi\displaystyle A(x)~=~\sum\limits_{i = 0}^{n - 1} a_i x^iA(x) = i=0∑n−1​ai​xi ,B(x)=∑i=0n−1bixi\displaystyle B(x)~=~\sum\limits_{i = 0}^{n - 1} b_i x^iB(x) = i=0∑n−1​bi​xi 的系数数列 {ai}\{a_i\}{ai​},对其进行离散傅里叶变换(DFT)得到的两个点值表示 {Adi}\{Ad_i\}{Adi​}, {Bdi}\{Bd_i\}{Bdi​},其中 Adk=∑i=0n−1ai×ωnik\displaystyle Ad_k~=~\sum\limits_{i = 0}^{n - 1} a_i \times \omega_n^{ik}Adk​ = i=0∑n−1​ai​×ωnik​,我们使用 FFT 在 O(nlogn)\mathcal O(nlogn)O(nlogn) 的时间复杂度下完成这一操作。

之后在 O(n)\mathcal O(n)O(n) 的时间复杂度下完成两个点值表示的多项式的乘积 Ci=Adi×BdiC_i=Ad_i\times Bd_iCi​=Adi​×Bdi​。

最后利用结论 ak=1n∑i=0n−1diωn−ki\displaystyle a_k~=~\frac{1}{n} \sum_{i = 0}^{n - 1} d_i \omega_n^{-ki}ak​ = n1​i=0∑n−1​di​ωn−ki​ ,通过逆离散傅里叶变换(IDFT)还原系数数列 {ci}\{c_i\}{ci​} 得到答案,同样使用 FFT 在 O(nlogn)\mathcal O(nlogn)O(nlogn) 的时间复杂度下完成这一操作。

我们借鉴多项式乘法即普通卷积的实现 FFT 得出类似的思路 FWT:

我们先根据多项式的系数表示,求出多项式的另一种表示:点值表示 FWT(A)FWT(A)FWT(A) ,然后在 O(n)\mathcal O(n)O(n) 下将对应的位置乘起来,最后复原即可。

即答案 FWT(C)=FWT(A)×FWT(B)\displaystyle FWT(C)=FWT(A)\times FWT(B)FWT(C)=FWT(A)×FWT(B)(其中 ×\times× 是 多项式 / 序列 对应位置相乘

看上去思路没有什么问题。我们考虑证明。

由于位运算卷积分为三种 ⊙=and,or,xor\odot=\text{and},\text{or},\text{xor}⊙=and,or,xor ,所以我们分开讨论。

0x11 或(or\text{or}or)卷积

或( or\text{or}or ,| ) 按位或运算符, |1110

或卷积: (f⊗org)k=∑i∣j=kfi×gj\displaystyle(f\otimes_{\text{or}} g)_k=\sum_{i| j=k}f_i\times g_j(f⊗or​g)k​=i∣j=k∑​fi​×gj​

对于序列 A,B,CA,B,CA,B,C,A={a0,a1⋯,an}A=\{a_0,a_1\cdots,a_{n}\}A={a0​,a1​⋯,an​},B={b0,b1,⋯,bn}B=\{b_0,b_1,\cdots,b_n\}B={b0​,b1​,⋯,bn​}, C={c0,c1,⋯cn}C=\{c_0,c_1,\cdots c_n\}C={c0​,c1​,⋯cn​} ,我们令 CCC 为或卷积的结果。

我们想要求的式子为 FWT(C)=FWT(A)×FWT(B)FWT(C)=FWT(A)\times FWT(B)FWT(C)=FWT(A)×FWT(B) ,即:ck=∑i∣j=kaibj\displaystyle c_{k}=\sum_{i \mid j=k} a_{i} b_{j}ck​=i∣j=k∑​ai​bj​

显然有 i∣k=k,j∣k=k→(i∣j)∣k=ki|k = k, j|k=k \to (i|j)|k=ki∣k=k,j∣k=k→(i∣j)∣k=k 。

因此我们构造快速沃尔什变换 FWTFWTFWT :FWT(A)[k]=∑i∣k=kai\displaystyle FWT(A)[k]=\sum_{i|k=k}a_iFWT(A)[k]=i∣k=k∑​ai​
FWT(A)×FWT(B)=(∑i∣k=kai)(∑j∣k=kbj)=∑i∣k=k,j∣k=kaibj=∑(i∣j)∣k=kaibj=FWT(C)\begin{aligned}FWT(A) \times FWT(B) &=\left(\sum_{i \mid k=k} a_{i}\right)\left(\sum_{j \mid k=k} b_{j}\right) \\&=\sum_{i|k=k,\ j| k=k} a_{i} b_{j} \\&=\sum_{(i \mid j) \mid k=k} a_{i} b_{j} \\&=FWT(C)\end{aligned} FWT(A)×FWT(B)​=⎝⎛​i∣k=k∑​ai​⎠⎞​⎝⎛​j∣k=k∑​bj​⎠⎞​=i∣k=k, j∣k=k∑​ai​bj​=(i∣j)∣k=k∑​ai​bj​=FWT(C)​


性质11.1: FWT(A±B)=FWT(A)±FWT(B)FWT(A\pm B)=FWT(A)\pm FWT(B)FWT(A±B)=FWT(A)±FWT(B)

根据 FWTFWTFWT 变换的定义我们可以将其看作是一个 AAA 序列的线性组合,故其加减法满足分配律。

由此我们可以得到 FWT 的递推式:

性质11.2:
FWT(A)={(FWT(A0),FWT(A0)+FWT(A1))n>1An=0FWT(A)=\begin{cases}(FWT(A_0),FWT(A_0)+FWT(A_1))& n>1\\\ A & n=0\end{cases} FWT(A)={(FWT(A0​),FWT(A0​)+FWT(A1​)) A​n>1n=0​
其中定义 AAA 为 2k2^k2k 多项式, A0A_0A0​ 代表 AAA 的系数序列的前半部分即前 2k−12^{k-1}2k−1 次项,A1A_1A1​ 代表 AAA 的后半部分即后 2k−12^{k-1}2k−1 次项,也就是下标的最高位分别为 000 和 111 的两部分。

式中的括号运算定义为: A=(B,C)A=(B,C)A=(B,C) 。

表示 BBB 这个多项式后面接上 CCC 等于 AAA,展开后为:
(A,B)=((a0,a1,a2⋯ax−1),(b0,b1,b2⋯by−1))=(a0,a1,a2⋯ax−1,b0,b1,b2⋯by−1)\begin{aligned}(A, B) &=\left(\left(a_{0}, a_{1}, a_{2} \cdots a_{x-1}\right),\left(b_{0}, b_{1}, b_{2} \cdots b_{y-1}\right)\right) \\&=\left(a_{0}, a_{1}, a_{2} \cdots a_{x-1}, b_{0}, b_{1}, b_{2} \cdots b_{y-1}\right)\end{aligned} (A,B)​=((a0​,a1​,a2​⋯ax−1​),(b0​,b1​,b2​⋯by−1​))=(a0​,a1​,a2​⋯ax−1​,b0​,b1​,b2​⋯by−1​)​
可以理解为系数直接连起来。

考虑证明:

首先 n=0n=0n=0 时显然成立。

我们知道 A0,A1A_0,A_1A0​,A1​ 实际上为下标的最高位分别为 000 和 111 的两部分,且除了最高位不同以外,其余的所有位,对于每一个下标 A1A_1A1​ 都有一个 A0A_0A0​ 与之相对应(仅最高位一个是 111 ,一个是 000)。

根据 FWT 的定义,合并之后左半部分下标的最高位仍然是 000,右半部分下标的最高位仍然是 111

首先对于左半部分:

由于 FWT(A1)FWT(A_1)FWT(A1​) 的最高位一定为 111,而此时 j∣ij|ij∣i 的最高位不可能为 000(1 | 0 = 1),所以右半部分在合并之后对于左半部分是没有贡献的,故 FWT(A)0=FWT(A0)FWT(A)_0=FWT(A_0)FWT(A)0​=FWT(A0​)。

而对于右半部分,如果左半部分的数满足 j∣i=ij|i=ij∣i=i,那么在 iii 加上最高位 111 之后, j∣i=ij|i=ij∣i=i 仍然成立。而此时右半部分的原来的 FWT(A1)FWT(A_1)FWT(A1​) 本来就对右半部分的数有贡献,故 FWT(A)1=FWT(A0)+FWT(A1)FWT(A)_1=FWT(A_0)+FWT(A_1)FWT(A)1​=FWT(A0​)+FWT(A1​)

故我们将这两部分使用括号运算合并即可得到:FWT(A)=(FWT(A0),FWT(A0)+FWT(A1))FWT(A)=(FWT(A_0),FWT(A_0)+FWT(A_1))FWT(A)=(FWT(A0​),FWT(A0​)+FWT(A1​))

性质11.2 得证。


性质11.3: FWT(A∣B)=FWT(A)×FWT(B)FWT(A|B)=FWT(A)\times FWT(B)FWT(A∣B)=FWT(A)×FWT(B)

(注,这里的 ×\times× 指对应系数相乘,见前排符号规定)

我们可以利用上面的 性质11.1 以及 性质11.2,使用数学归纳法证明:

FWT(A∣B)=FWT((A∣B)0,(A∣B)1)=FWT(A0∣B0,A0∣B1+A1∣B0+A1∣B1)=(FWT(A0∣B0),FWT(A0∣B0+A0∣B1+A1∣B0+A1∣B1))=(FWT(A0)×FWT(B0),FWT(A0)×FWT(B0)+FWT(A0)×FWT(B1)+FWT(A1)×FWT(B0)+FWT(A1)×FWT(B1))=(FWT(A0)×FWT(B0),(FWT(A0)+FWT(A1))×(FWT(B0)+FWT(B1)))=(FWT(A0),FWT(A0+A1))×(FWT(B0),FWT(B0+B1))=FWT(A)×FWT(B)\begin{aligned} FWT(A|B)=&FWT((A|B)_0,(A|B)_1)\\ =&FWT(A_0|B_0,A_0|B_1+A_1|B_0+A_1|B_1)\\ =&(FWT(A_0|B_0),FWT(A_0|B_0+A_0|B_1+A_1|B_0+A_1|B_1))\\ =&(FWT(A_0)\times FWT(B_0)\\&,FWT(A_0)\times FWT(B_0)+FWT(A_0)\times FWT(B_1)+FWT(A_1)\times FWT(B_0)+FWT(A_1)\times FWT(B_1))\\ =&(FWT(A_0)\times FWT(B_0),(FWT(A_0)+FWT(A_1))\times (FWT(B_0)+FWT(B_1)))\\ =&(FWT(A_0),FWT(A_0+A_1))\times (FWT(B_0),FWT(B_0+B_1))\\ =&FWT(A)\times FWT(B) \end{aligned} FWT(A∣B)=======​FWT((A∣B)0​,(A∣B)1​)FWT(A0​∣B0​,A0​∣B1​+A1​∣B0​+A1​∣B1​)(FWT(A0​∣B0​),FWT(A0​∣B0​+A0​∣B1​+A1​∣B0​+A1​∣B1​))(FWT(A0​)×FWT(B0​),FWT(A0​)×FWT(B0​)+FWT(A0​)×FWT(B1​)+FWT(A1​)×FWT(B0​)+FWT(A1​)×FWT(B1​))(FWT(A0​)×FWT(B0​),(FWT(A0​)+FWT(A1​))×(FWT(B0​)+FWT(B1​)))(FWT(A0​),FWT(A0​+A1​))×(FWT(B0​),FWT(B0​+B1​))FWT(A)×FWT(B)​


当然我们也可以使用定义将其展开来证明,这样看上去会会更加的清晰一些。

其中若 i∣k=k,j∣k=k→(i∣j)∣k=ki|k=k,j|k=k\to (i|j)|k=ki∣k=k,j∣k=k→(i∣j)∣k=k。

FWT(A)×FWT(B)=(∑i∣0=0ai,∑i∣1=1ai,∑i∣2=2ai⋯∑i∣(n−1)=(n−1)ai)×(∑i∣0=0bi,∑i∣1=1bi,∑i∣2=2bi⋯∑i∣(n−1)=(n−1)bi)=((∑i∣0=0ai)×(∑j∣0=0bj),(∑i∣1=1ai)×(∑j∣1=1bj),(∑i∣2=2ai)×(∑j∣2=2bj)⋯(∑i∣(n−1)=(n−1)ai)×(∑j∣(n−1)=(n−1)bj))=(∑i∣j∣0=0ai×bj,∑i∣j∣1=1ai×bj,∑i∣j∣2=2ai×bj⋯∑i∣j∣(n−1)=(n−1)ai×bj)=(∑k∣0=0∑i∣j=kai×bj,∑k∣1=1∑i∣j=kai×bj,∑k∣2=2∑i∣j=kai×bj⋯∑k∣(n−1)=(n−1)∑i∣j=kai×bj)=FWT(A∣B)\begin{aligned}FWT(A) \times F W T(B) &=\left(\sum_{i \mid 0=0} a_{i}, \sum_{i \mid 1=1} a_{i}, \sum_{i \mid 2=2} a_{i} \cdots \sum_{i \mid(n-1)=(n-1)} a_{i}\right) \times \left(\sum_{i \mid 0=0} b_{i}, \sum_{i \mid 1=1} b_{i}, \sum_{i \mid 2=2} b_{i} \cdots \sum_{i \mid(n-1)=(n-1)} b_{i}\right) \\&=\left(\left(\sum_{i \mid 0=0} a_{i}\right) \times \left(\sum_{j \mid 0=0} b_{j}\right),\left(\sum_{i \mid 1=1} a_{i}\right) \times \left(\sum_{j \mid 1=1} b_{j}\right),\left(\sum_{i \mid 2=2} a_{i}\right) \times \left(\sum_{j \mid 2=2} b_{j}\right) \cdots\left(\sum_{i \mid(n-1)=(n-1)} a_{i}\right) \times \left(\sum_{j \mid(n-1)=(n-1)} b_{j}\right)\right) \\&=\left(\sum_{i|j| 0=0} a_{i} \times b_{j}, \sum_{i|j| 1=1} a_{i}\times b_{j}, \sum_{i|j| 2=2} a_{i} \times b_{j} \cdots \sum_{i|j|(n-1)=(n-1)} a_{i} \times b_{j}\right) \\&=\left(\sum_{k \mid 0=0} \sum_{i \mid j=k} a_{i} \times b_{j}, \sum_{k \mid 1=1} \sum_{i \mid j=k} a_{i} \times b_{j}, \sum_{k \mid 2=2} \sum_{i \mid j=k} a_{i} \times b_{j} \cdots \sum_{k \mid(n-1)=(n-1)} \sum_{i \mid j=k} a_{i} \times b_{j}\right) \\&=F W T(A \mid B)\end{aligned} FWT(A)×FWT(B)​=⎝⎛​i∣0=0∑​ai​,i∣1=1∑​ai​,i∣2=2∑​ai​⋯i∣(n−1)=(n−1)∑​ai​⎠⎞​×⎝⎛​i∣0=0∑​bi​,i∣1=1∑​bi​,i∣2=2∑​bi​⋯i∣(n−1)=(n−1)∑​bi​⎠⎞​=⎝⎛​⎝⎛​i∣0=0∑​ai​⎠⎞​×⎝⎛​j∣0=0∑​bj​⎠⎞​,⎝⎛​i∣1=1∑​ai​⎠⎞​×⎝⎛​j∣1=1∑​bj​⎠⎞​,⎝⎛​i∣2=2∑​ai​⎠⎞​×⎝⎛​j∣2=2∑​bj​⎠⎞​⋯⎝⎛​i∣(n−1)=(n−1)∑​ai​⎠⎞​×⎝⎛​j∣(n−1)=(n−1)∑​bj​⎠⎞​⎠⎞​=⎝⎛​i∣j∣0=0∑​ai​×bj​,i∣j∣1=1∑​ai​×bj​,i∣j∣2=2∑​ai​×bj​⋯i∣j∣(n−1)=(n−1)∑​ai​×bj​⎠⎞​=⎝⎛​k∣0=0∑​i∣j=k∑​ai​×bj​,k∣1=1∑​i∣j=k∑​ai​×bj​,k∣2=2∑​i∣j=k∑​ai​×bj​⋯k∣(n−1)=(n−1)∑​i∣j=k∑​ai​×bj​⎠⎞​=FWT(A∣B)​


至此,我们得到了与 FFT 类似的 FWT 的所有定义与性质。

根据 FFT 的流程,我们需要定义 IFWT,即逆沃尔什变换。

我们定义 IFWT(FWT(A))=AIFWT(FWT(A))=AIFWT(FWT(A))=A。

则:
IFWT(A)={(IFWT(A0),IFWT(A1)−IFWT(A0))n>1An=0IFWT(A)=\begin{cases}(IFWT(A_0),IFWT(A_1)-IFWT(A_0))&n>1\\\ A&n=0\end{cases} IFWT(A)={(IFWT(A0​),IFWT(A1​)−IFWT(A0​)) A​n>1n=0​
考虑证明:

根据 性质11.1
∵FWT(A)0=FWT(A0)∴A0=IFWT⁡(FWT(A0))=IFWT⁡(FWT(A)0)∵FWT(A)1=FWT(A0)+FWT(A1)∴A1=IFWT(FWT(A1))=IFWT(FWT(A)1−FWT(A)0)∴IFWT(A)=IFWT((A0,A1))=(IFWT(A0),IFWT(A1)−IFWT(A0))\begin{aligned}&\\&\because F W T(A)_{0}=F W T\left(A_{0}\right)\\&\therefore A_{0}=\operatorname{IFWT}\left(F W T\left(A_{0}\right)\right)=\operatorname{IFWT}\left(F W T(A)_{0}\right)\\&\because F W T(A)_{1}=F W T\left(A_{0}\right)+F W T\left(A_{1}\right)\\&\therefore A_{1}=I FW T\left(F W T\left(A_{1}\right)\right)=I FW T\left(F W T(A)_{1}-F W T(A)_{0}\right)\\& \therefore IFWT(A)=IFWT((A_0, A_1))=(IFWT(A_0),IFWT(A_1)-IFWT(A_0))\end{aligned} ​∵FWT(A)0​=FWT(A0​)∴A0​=IFWT(FWT(A0​))=IFWT(FWT(A)0​)∵FWT(A)1​=FWT(A0​)+FWT(A1​)∴A1​=IFWT(FWT(A1​))=IFWT(FWT(A)1​−FWT(A)0​)∴IFWT(A)=IFWT((A0​,A1​))=(IFWT(A0​),IFWT(A1​)−IFWT(A0​))​
其实看起来非常的形象,因为 IFWT 是 FWT 的逆运算,所以公式逆过来, +++ 变成 −-− 就行了。

显然FWT与IFWT运算基本相同,实现的时候写成一个函数即可:

inline void OR(int *f, int x = 1) {for (int o = 2, k = 1; o <= n; o <<= 1, k <<= 1)for (int i = 0; i < n; i += o)for (int j = 0; j < k; ++ j)f[i + j + k] += f[i + j] * x;
}

0x12 与(and\text{and}and)卷积

同理,我们可以得到与卷积的定义式:
FWT(A)[k]=∑i&k=kaiFWT(A)[k]=\sum_{i\&k=k}a_i FWT(A)[k]=i&k=k∑​ai​
以及 FWT 的递推式:
FWT(A)={(FWT(A0)+FWT(A1),FWT(A1))n>1An=0FWT(A)=\begin{cases}(FWT(A_0)+FWT(A_1),FWT(A_1))&n>1\\\ A &n=0\end{cases} FWT(A)={(FWT(A0​)+FWT(A1​),FWT(A1​)) A​n>1n=0​

证明同或卷积,序列 AAA 的右半部分任意一个下标 &\&& 左半部分即首位为 000 的数,得到的结果一定在 AAA 的左半部分,故 A1A_1A1​ 对 左半部分有贡献,且一定对自己所在的右半部分有贡献。

性质12.1: FWT(A&B)=FWT(A)×FWT(B)FWT(A\&B)=FWT(A)\times FWT(B)FWT(A&B)=FWT(A)×FWT(B)

证明:

我们仍然利用性质11.1,使用数学归纳法证明
FWT(A&B)=FWT((A&B)0,(A&B)1)=FWT(A0&B0+A0&B1+A1&B0,A1&B1)=(FWT(A0&B0+A0&B1+A1&B0+A1&B1),FWT(A1&B1))=((FWT(A0)+FWT(A1))×(FWT(B0)+FWT(B1)),FWT(A1)×FWT(B1))=(FWT(A0)+FWT(A1),FWT(A1))×(FWT(B0)+FWT(B1),FWT(B1))=FWT(A)×FWT(B)\begin{aligned} FWT(A\&B)&=FWT((A\&B)_0,(A\&B)_1)\\ &=FWT(A_0\&B_0+A_0\&B_1+A_1\&B_0,A_1\&B_1)\\ &=(FWT(A_0\&B_0+A_0\&B_1+A_1\&B_0+A_1\&B_1),FWT(A_1\&B_1))\\ &=((FWT(A_0)+FWT(A_1))\times (FWT(B_0)+FWT(B_1)),FWT(A_1)\times FWT(B_1))\\ &=(FWT(A_0)+FWT(A_1),FWT(A_1))\times (FWT(B_0)+FWT(B_1),FWT(B_1))\\ &=FWT(A)\times FWT(B) \end{aligned} FWT(A&B)​=FWT((A&B)0​,(A&B)1​)=FWT(A0​&B0​+A0​&B1​+A1​&B0​,A1​&B1​)=(FWT(A0​&B0​+A0​&B1​+A1​&B0​+A1​&B1​),FWT(A1​&B1​))=((FWT(A0​)+FWT(A1​))×(FWT(B0​)+FWT(B1​)),FWT(A1​)×FWT(B1​))=(FWT(A0​)+FWT(A1​),FWT(A1​))×(FWT(B0​)+FWT(B1​),FWT(B1​))=FWT(A)×FWT(B)​


或是继续展开证明:

FWT(A)×FWT(B)=(∑i&0=0ai,∑i&1=1ai,∑i&2=2ai⋯∑i&(n−1)=(n−1)ai)×(∑i&0=0bi,∑i&1=1bi,∑i&2=2bi⋯∑i&(n−1)=(n−1)bi)=((∑i&0=0ai)×(∑j&0=0bj),(∑i&1=1ai)×(∑j&1=1bj),(∑i&2=2ai)×(∑j&2=2bj)⋯(∑i&(n−1)=(n−1)ai)×(∑j&(n−1)=(n−1)bj))=(∑i&j&0=0ai×bj,∑i&j&1=1ai×bj,∑i&j&2=2ai×bj⋯∑i&j&(n−1)=(n−1)ai×bj)=(∑k&0=0∑i&j=kai∗bj,∑k&1=1∑i&j=kai×bj,∑k&2=2∑i&j=kai×bj⋯∑k&(n−1)=(n−1)∑i&j=kai×bj)=FWT(A&B)\begin{aligned}F W T(A) \times F W T(B)&=\left(\sum_{i \& 0=0} a_{i}, \sum_{i \& 1=1} a_{i}, \sum_{i \& 2=2} a_{i} \cdots \sum_{i \&(n-1)=(n-1)} a_{i}\right) \times \left(\sum_{i \& 0=0} b_{i}, \sum_{i \& 1=1} b_{i}, \sum_{i \& 2=2} b_{i} \cdots \sum_{i \&(n-1)=(n-1)} b_{i}\right)\\&=\left(\left(\sum_{i \& 0=0} a_{i}\right) \times \left(\sum_{j \& 0=0} b_{j}\right),\left(\sum_{i \& 1=1} a_{i}\right) \times \left(\sum_{j \& 1=1} b_{j}\right),\left(\sum_{i \& 2=2} a_{i}\right) \times \left(\sum_{j \& 2=2} b_{j}\right) \cdots\left(\sum_{i \&(n-1)=(n-1)} a_{i}\right) \times \left(\sum_{j \&(n-1)=(n-1)} b_{j}\right)\right)\\&=\left(\sum_{i \& j \& 0=0} a_{i} \times b_{j}, \sum_{i \& j \& 1=1} a_{i} \times b_{j}, \sum_{i \& j \& 2=2} a_{i} \times b_{j} \cdots \sum_{i \& j \&(n-1)=(n-1)} a_{i} \times b_{j}\right)\\&=\left(\sum_{k \& 0=0} \sum_{i \& j=k} a_{i} * b_{j}, \sum_{k \& 1=1} \sum_{i \& j=k} a_{i} \times b_{j}, \sum_{k \& 2=2} \sum_{i \& j=k} a_{i} \times b_{j} \cdots \sum_{k \&(n-1)=(n-1)} \sum_{i \& j=k} a_{i} \times b_{j}\right)\\&=F W T(A \& B)\end{aligned} FWT(A)×FWT(B)​=⎝⎛​i&0=0∑​ai​,i&1=1∑​ai​,i&2=2∑​ai​⋯i&(n−1)=(n−1)∑​ai​⎠⎞​×⎝⎛​i&0=0∑​bi​,i&1=1∑​bi​,i&2=2∑​bi​⋯i&(n−1)=(n−1)∑​bi​⎠⎞​=⎝⎛​(i&0=0∑​ai​)×⎝⎛​j&0=0∑​bj​⎠⎞​,(i&1=1∑​ai​)×⎝⎛​j&1=1∑​bj​⎠⎞​,(i&2=2∑​ai​)×⎝⎛​j&2=2∑​bj​⎠⎞​⋯⎝⎛​i&(n−1)=(n−1)∑​ai​⎠⎞​×⎝⎛​j&(n−1)=(n−1)∑​bj​⎠⎞​⎠⎞​=⎝⎛​i&j&0=0∑​ai​×bj​,i&j&1=1∑​ai​×bj​,i&j&2=2∑​ai​×bj​⋯i&j&(n−1)=(n−1)∑​ai​×bj​⎠⎞​=⎝⎛​k&0=0∑​i&j=k∑​ai​∗bj​,k&1=1∑​i&j=k∑​ai​×bj​,k&2=2∑​i&j=k∑​ai​×bj​⋯k&(n−1)=(n−1)∑​i&j=k∑​ai​×bj​⎠⎞​=FWT(A&B)​

我们定义逆沃尔什变换 IFWT(FWT(A))=AIFWT(FWT(A))=AIFWT(FWT(A))=A。

则:
IFWT(A)={(IFWT(A0)−IFWT(A1),IFWT(A1))n>1An=0IFWT(A)=\begin{cases}(IFWT(A_0)-IFWT(A_1),IFWT(A_1))&n>1\\\ A&n=0\end{cases} IFWT(A)={(IFWT(A0​)−IFWT(A1​),IFWT(A1​)) A​n>1n=0​

考虑证明:

n=0n=0n=0 时正确性显然。

根据 性质11.1
FWT(A)0=FWT(A0)+FWT(A1)∴A0=IDFT(FWT(A0))=IDFT(FWT(A)0−FWT(A)1)=IFWT(A0)−IFWT(A1)∵FWT(A)1=FWT(A1)∴A1=IDFT(FWT(A1))=IDFT(FWT(A)1)∴IFWT(A)=IFWT((A0,A1))=(IFWT(A0)−IFWT(A1),IFWT(A1))\begin{aligned}& F W T(A)_{0}=F W T\left(A_{0}\right)+F W T\left(A_{1}\right)\\&\therefore A_{0}=I D F T\left(F W T\left(A_{0}\right)\right)=I D F T\left(F W T(A)_{0}-F W T(A)_{1}\right)=IFWT(A_0)-IFWT(A_1)\\&\because F W T(A)_{1}=F W T\left(A_{1}\right)\\&\therefore A_{1}=I D F T\left(F W T\left(A_{1}\right)\right)=I D F T\left(F W T(A)_{1}\right)\\& \therefore IFWT(A)=IFWT((A_0, A_1))=(IFWT(A_0)-IFWT(A_1),IFWT(A_1))\end{aligned} ​FWT(A)0​=FWT(A0​)+FWT(A1​)∴A0​=IDFT(FWT(A0​))=IDFT(FWT(A)0​−FWT(A)1​)=IFWT(A0​)−IFWT(A1​)∵FWT(A)1​=FWT(A1​)∴A1​=IDFT(FWT(A1​))=IDFT(FWT(A)1​)∴IFWT(A)=IFWT((A0​,A1​))=(IFWT(A0​)−IFWT(A1​),IFWT(A1​))​
同或卷积,我们同样可以得到一份代码:

inline void AND(int *f, int x = 1) {for (int o = 2, k = 1; o <= n; o <<= 1, k <<= 1)for (int i = 0; i < n; i += o)for (int j = 0; j < k; ++ j)f[i+j] += f[i+j+k] * x;
}

0x13 异或(xor\text{xor}xor)卷积

异或卷积与或卷积、与卷积稍有不同。

我们定义函数 d(x)d(x)d(x) 表示 xxx 在二进制下 111 的数量

定义 FWT 变换为:
FWT(A)[i]=∑d(j&i)≡0mod2Aj−∑d(k&i)≡1mod2AkFWT(A)[i]=\sum_{d(j\&i)\equiv0\mod 2}A_j-\sum_{d(k\&i)\equiv1\mod 2}A_k FWT(A)[i]=d(j&i)≡0mod2∑​Aj​−d(k&i)≡1mod2∑​Ak​
则可得到递推式:
FWT(A)={(FWT(A0)+FWT(A1),FWT(A0)−FWT(A1))n>0An=0FWT(A)=\begin{cases}(FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))&n>0\\\ A&n=0\end{cases} FWT(A)={(FWT(A0​)+FWT(A1​),FWT(A0​)−FWT(A1​)) A​n>0n=0​
考虑证明:

首先左半部分的公式为:FWT(A0)+FWT(A1)FWT(A_0)+FWT(A_1)FWT(A0​)+FWT(A1​)

因为 A0A_0A0​ 即前 2k−12^{k-1}2k−1 项下标 [0,2k−1][0,2^{k-1}][0,2k−1] 的最高位都为 000,故 A0A_0A0​ 的下标与 A0A_0A0​ “与” 运算之后最高位不变,仍然是 000 ,所以要加上A0A_0A0​ 的贡献 FWT(A0)FWT(A_0)FWT(A0​), A1A_1A1​ 的下标在与 A0A_0A0​ “与”运算之后,最高位 1and 0=01\ \text{and}\ 0=01 and 0=0 ,故后半部分也会对前半部分有贡献。

右半部分的公式为:FWT(A0)−FWT(A1)FWT(A_0)−FWT(A_1)FWT(A0​)−FWT(A1​)

同理 A0A_0A0​ 的下标和 A1A_1A1​ “与” 运算之后最高位保持不变。而 A1A_1A1​ 的下标的最高位多了一个 111,“与” 上一个最高位为 111 的数之后奇偶性就变了,所以要取反 。


性质13.1: FWT(A⊕B)=FWT(A)×FWT(B)FWT(A\oplus B)=FWT(A)\times FWT(B)FWT(A⊕B)=FWT(A)×FWT(B)

该性质在这里同样成立。

证明:
FWT(A⊕B)=FWT((A⊕B)0,(A⊕B)1)=FWT(A0⊕B0+A1⊕B1,A0⊕B1+A1⊕B0)=(FWT(A0⊕B0+A1⊕B1+A0⊕B1+A1⊕B0),FWT(A0⊕B0+A1⊕B1−A0⊕B1−A1⊕B0))=((FWT(A0)+FWT(A1))×(FWT(B0)+FWT(B1)),(FWT(A0)−FWT(A1))×(FWT(B0)−FWT(B1)))=(FWT(A0+A1),FWT(A0−A1))×(FWT(B0+B1),FWT(B0−B1))=FWT(A)×FWT(B)\begin{aligned} FWT(A\oplus B)&=FWT((A\oplus B)_0,(A\oplus B)_1)\\ &=FWT(A_0\oplus B_0+A_1\oplus B_1,A_0\oplus B_1+A_1\oplus B_0)\\\ &=(FWT(A_0\oplus B_0+A_1\oplus B_1+A_0\oplus B_1+A_1\oplus B_0),\\ &FWT(A_0\oplus B_0+A_1\oplus B_1-A_0\oplus B_1-A_1\oplus B_0))\\ &=((FWT(A_0)+FWT(A_1))\times (FWT(B_0)+FWT(B_1)),\\ &(FWT(A_0)-FWT(A_1))\times (FWT(B_0)-FWT(B_1)))\\ &=(FWT(A_0+A_1),FWT(A_0-A_1))\times (FWT(B_0+B_1),FWT(B_0-B_1))\\ &=FWT(A)\times FWT(B) \end{aligned} FWT(A⊕B) ​=FWT((A⊕B)0​,(A⊕B)1​)=FWT(A0​⊕B0​+A1​⊕B1​,A0​⊕B1​+A1​⊕B0​)=(FWT(A0​⊕B0​+A1​⊕B1​+A0​⊕B1​+A1​⊕B0​),FWT(A0​⊕B0​+A1​⊕B1​−A0​⊕B1​−A1​⊕B0​))=((FWT(A0​)+FWT(A1​))×(FWT(B0​)+FWT(B1​)),(FWT(A0​)−FWT(A1​))×(FWT(B0​)−FWT(B1​)))=(FWT(A0​+A1​),FWT(A0​−A1​))×(FWT(B0​+B1​),FWT(B0​−B1​))=FWT(A)×FWT(B)​

同样可以展开来证明:
FWT(A×B)=(∑(−1)pc(i&0)ai,∑(−1)pc(i&1)ai⋯∑(−1)pc(i&(n−1))ai)×(∑(−1)pc(i&0)bi,∑(−1)pc(i&1)bi⋯∑p(−1)pc(i&(n−1))bi)=((∑(−1)pc(i&0)ai)×((∑(−1)pc(j&0)bj)),(∑(−1)pc(i&1)ai)×(∑(−1)pc(j&1)bj)⋯(∑(−1)pc(i&(n−1)ai)×(∑(−1)pc(j&(n−1))bj))=(∑(−1)pc(i⊕j&0)ai×bj,(∑(−1)pc(i⊕j&1)ai×bj⋯(∑(−1)pc(i⊕j&(n−1))ai×bj)=(∑(−1)pc(k&0)∑i⊕j=kai×bj,∑(−1)pc(k&1)∑i⊕j=kai×bj⋯∑(−1)pc(k&(n−1))∑i⊕j=kai×bj)=FWT(A⊕B)\begin{aligned}FWT(A\times B)&=\left(\sum(-1)^{p c(i \& 0)} a_{i}, \sum(-1)^{p c(i \& 1)} a_{i} \cdots \sum(-1)^{p c(i \&(n-1))} a_{i}\right) \times \left(\sum(-1)^{p c(i \& 0)} b_{i}, \sum(-1)^{p c(i \& 1)} b_{i} \cdots \sum_{ }^{p}\left.(-1)^{p c(i \&(n-1))} b_{i}\right)\right.\\&=\left(\left(\sum(-1)^{p c(i \& 0)} a_{i}\right) \times \left(\left(\sum(-1)^{p c(j \& 0)} b_{j}\right)\right),\left(\sum(-1)^{p c(i \& 1)} a_{i}\right) \times \left(\sum(-1)^{p c(j \& 1)} b_{j}\right) \cdots\left(\sum(-1)^{p c(i \&(n-1)}a_{i}\right)\right.\left.\left.\right. \times\left(\sum(-1)^{p c(j \&(n-1))} b_{j}\right)\right)\\&=\left(\sum(-1)^{p c(i \oplus j \& 0)} a_{i} \times b_{j},\left(\sum(-1)^{p c(i \oplus j \& 1)} a_{i} \times b_{j} \cdots\left(\sum(-1)^{p c(i \oplus j \&(n-1))} a_{i} \times b_{j}\right)\right.\right.\\&=\left(\sum(-1)^{p c(k \& 0)} \sum_{i \oplus j=k} a_{i} \times b_{j}, \sum(-1)^{p c(k \& 1)} \sum_{i \oplus j=k} a_{i} \times b_{j} \cdots \sum(-1)^{p c(k \&(n-1))} \sum_{i \oplus j=k} a_{i} \times b_{j}\right)\\&=F W T(A \oplus B)\end{aligned} FWT(A×B)​=(∑(−1)pc(i&0)ai​,∑(−1)pc(i&1)ai​⋯∑(−1)pc(i&(n−1))ai​)×(∑(−1)pc(i&0)bi​,∑(−1)pc(i&1)bi​⋯∑p​(−1)pc(i&(n−1))bi​)=((∑(−1)pc(i&0)ai​)×((∑(−1)pc(j&0)bj​)),(∑(−1)pc(i&1)ai​)×(∑(−1)pc(j&1)bj​)⋯(∑(−1)pc(i&(n−1)ai​)×(∑(−1)pc(j&(n−1))bj​))=(∑(−1)pc(i⊕j&0)ai​×bj​,(∑(−1)pc(i⊕j&1)ai​×bj​⋯(∑(−1)pc(i⊕j&(n−1))ai​×bj​)=⎝⎛​∑(−1)pc(k&0)i⊕j=k∑​ai​×bj​,∑(−1)pc(k&1)i⊕j=k∑​ai​×bj​⋯∑(−1)pc(k&(n−1))i⊕j=k∑​ai​×bj​⎠⎞​=FWT(A⊕B)​
我们定义逆沃尔什变换 IFWT(FWT(A))=AIFWT(FWT(A))=AIFWT(FWT(A))=A。

则:
IFWT(A)={(IFWT(A0+A1)2,IFWT(A0−A1)2)n>1An=0IFWT(A)=\begin{cases}(\cfrac{IFWT(A_0+A_1)}{2},\cfrac{IFWT(A_0-A_1)}{2})&n>1\\\ A&n=0\end{cases} IFWT(A)=⎩⎨⎧​(2IFWT(A0​+A1​)​,2IFWT(A0​−A1​)​) A​n>1n=0​
考虑证明:

n=0n=0n=0 时正确性显然。

根据 性质11.1
∵FWT(A)0=FWT(A0)+FWT(A1),FWT(A)1=FWT(A0)−FWT(A1)∴A0=IDFT(FWT(A0))=IDFT(FWT(A)0+FWT(A)12)A1=IDFT(FWT(A1))=IDFT(FWT(A)0−FWT(A)12)∴IFWT(A)=IFWT((A0,A1))=(IFWT(A0+A1)2,IFWT(A0−A1)2)\begin{aligned} & \because F W T(A)_{0}=F W T\left(A_{0}\right)+F W T\left(A_{1}\right), F W T(A)_{1}=F W T\left(A_{0}\right)-F W T\left(A_{1}\right) \\&\therefore A_{0}=I D F T\left(F W T\left(A_{0}\right)\right)=I D F T\left(\frac{F W T(A)_{0}+F W T(A)_{1}}{2}\right)\\& A_{1}=I D F T\left(F W T\left(A_{1}\right)\right)= I D F T\left(\frac{F W T(A)_{0}-F W T(A)_{1}}{2}\right)\\& \therefore IFWT(A)=IFWT((A_0, A_1))=(\frac{IFWT(A_0+A_1)}{2},\frac{IFWT(A_0-A_1)}{2})\end{aligned} ​∵FWT(A)0​=FWT(A0​)+FWT(A1​),FWT(A)1​=FWT(A0​)−FWT(A1​)∴A0​=IDFT(FWT(A0​))=IDFT(2FWT(A)0​+FWT(A)1​​)A1​=IDFT(FWT(A1​))=IDFT(2FWT(A)0​−FWT(A)1​​)∴IFWT(A)=IFWT((A0​,A1​))=(2IFWT(A0​+A1​)​,2IFWT(A0​−A1​)​)​

inline void XOR(int *f, int x = 1) {for (int o = 2, k = 1; o <= n; o <<= 1, k <<= 1)for (int i = 0; i < n; i += o)for (int j = 0; j < k; ++ j)f[i + j] += f[i + j + k],f[i + j + k] = f[i + j] - f[i + j + k] - f[i + j + k],f[i + j] *= x, f[i+j+k] *= x;
}

0x14 模板

luogu P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT)

题目描述

给定长度为 2n2^n2n 两个序列 A,BA,BA,B 设

Ci=∑j⊕k=iAj×BkC_i=\sum_{j\oplus k = i}A_j \times B_kCi​=∑j⊕k=i​Aj​×Bk​

分别当 ⊕\oplus⊕ 是 or,and,xoror,and,xoror,and,xor 时求出 CCC

输入格式

第一行一个数 nnn 。 第二行 2n2^n2n 个数 A0..A2n−1A_0..A_{2^n-1}A0​..A2n−1​ 第三行 2n2^n2n 个数 B0..B2n−1B_0..B_{2^n-1}B0​..B2n−1​

输出格式

三行每行 2n2^n2n 个数,分别代表 ⊕\oplus⊕ 是 or,and,xoror,and,xoror,and,xor 时 C0..C2n−1C_0..C_{2^n-1}C0​..C2n−1​ 的值mod998244353\bmod\ 998244353mod 998244353

输入输出样例

输入

2
2 4 6 8
1 3 5 7

输出

2 22 46 250
88 64 112 56
100 92 68 60

说明/提示

n≤17n\le 17n≤17

Code

数组版:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>using namespace std;
typedef long long ll;
typedef int itn;
const int N = (1 << 18) + 7, mod = 998244353;
const ll INF = 4e18;int n, m;
ll A[N], B[N], a[N], b[N];ll qpow(ll a, ll b)
{ll res = 1;while(b) {if(b & 1) res = 1ll * res * a % mod;a = 1ll * a * a % mod;b >>= 1;}return res;
}ll inv2 = qpow(2, mod - 2);inline void in()
{for(int i = 0; i < n; ++ i)a[i] = A[i], b[i] = B[i];
}inline void get()
{for(int i = 0; i < n; ++ i)a[i] = a[i] * b[i] % mod;
}inline void out()
{for(int i = 0; i < n; ++ i)printf("%lld%s", (a[i] % mod + mod) % mod, i == (n - 1) ? "\n" : " ");
}inline void OR(ll *f, int x = 1)//前半部分 f[i + j], 后半部分 f[i + j + k]
{for(int o = 2; o <= n; o <<= 1)for(int i = 0, k = o >> 1; i < n; i += o)for(int j = 0; j < k; ++ j)f[i + j + k] = (f[i + j] * x + f[i + j + k] + (x == 1 ? 0 : mod)) % mod;}inline void AND(ll *f, int x = 1)//前半部分 f[i + j],后半部分 f[i + j + k]
{for(int o = 2; o <= n; o <<= 1)for(int i = 0, k = o >> 1; i < n; i += o)for(int j = 0; j < k; ++ j)f[i + j] = (f[i + j] + f[i + j + k] * x + (x == 1 ? 0 : mod)) % mod;}inline void XOR(ll *f, int x = 1)//前半部分 f[i + j],后半部分 f[i + j + k]
{for(int o = 2; o <= n; o <<= 1)for(int i = 0, k = o >> 1; i < n; i += o)for(int j = 0; j < k; ++ j) {int X = f[i + j], Y = f[i + j + k];f[i + j] = (X + Y) % mod;f[i + j + k] = (X - Y % mod + mod) % mod;if(x != 1) {f[i + j] = f[i + j] * inv2 % mod;f[i + j + k] = f[i + j + k] * inv2 % mod;}}
}int main()
{scanf("%d", &m);n = 1 << m;for(int i = 0; i < n; ++ i)scanf("%lld", &A[i]);for(int i = 0; i < n; ++ i)scanf("%lld", &B[i]);in(), OR(a), OR(b), get(), OR(a, -1), out();in(), AND(a), AND(b), get(), AND(a, -1), out();in(), XOR(a), XOR(b), get(), XOR(a, -1), out();return 0;
}

vector 版:

#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;const int N = 50007, P = 998244353;
int n, m;void add(int &x, int y) {(x += y) >= P && (x -= P);
}
void sub(int &x, int y) {(x -= y) < 0 && (x += P);
}
struct FWT {int extend(int n) {int N = 1;for (; N < n; N <<= 1);return N;}void FWTor( vector<int> &a, bool rev) {int n = a.size();for (int l = 2, m = 1; l <= n; l <<= 1, m <<= 1) {for (int j = 0; j < n; j += l) for (int i = 0; i < m; i++) {if (!rev) add(a[i + j + m], a[i + j]);else sub(a[i + j + m], a[i + j]);}}}void FWTand( vector<int> &a, bool rev) {int n = a.size();for (int l = 2, m = 1; l <= n; l <<= 1, m <<= 1) {for (int j = 0; j < n; j += l) for (int i = 0; i < m; i++) {if (!rev) add(a[i + j], a[i + j + m]);else sub(a[i + j], a[i + j + m]);}}}void FWTxor( vector<int> &a, bool rev) {int n = a.size(), inv2 = (P + 1) >> 1;for (int l = 2, m = 1; l <= n; l <<= 1, m <<= 1) {for (int j = 0; j < n; j += l) for (int i = 0; i < m; i++) {int x = a[i + j], y = a[i + j + m];if (!rev) {a[i + j] = (x + y) % P;a[i + j + m] = (x - y + P) % P;} else {a[i + j] = 1LL * (x + y) * inv2 % P;a[i + j + m] = 1LL * (x - y + P) * inv2 % P;}}}}vector<int> Or(vector<int> a1, vector<int> a2) {int n = max(a1.size(), a2.size()), N = extend(n);a1.resize(N), FWTor(a1, false);a2.resize(N), FWTor(a2, false);vector<int> A(N);for (int i = 0; i < N; i++) A[i] = 1LL * a1[i] * a2[i] % P;FWTor(A, true);return A;}vector<int> And(vector<int> a1, vector<int> a2) {int n =  max(a1.size(), a2.size()), N = extend(n);a1.resize(N), FWTand(a1, false);a2.resize(N), FWTand(a2, false);vector<int> A(N);for (int i = 0; i < N; i++) A[i] = 1LL * a1[i] * a2[i] % P;FWTand(A, true);return A;}vector<int> Xor(vector<int> a1, vector<int> a2) {int n = max(a1.size(), a2.size()), N = extend(n);a1.resize(N), FWTxor(a1, false);a2.resize(N), FWTxor(a2, false);vector<int> A(N);for (int i = 0; i < N; i++) A[i] = 1LL * a1[i] * a2[i] % P;FWTxor(A, true);return A;}
} fwt;int main() {scanf("%d", &m);n = 1 << m;vector<int> a1(n), a2(n);for (int i = 0; i < n; i++) scanf("%d", &a1[i]);for (int i = 0; i < n; i++) scanf("%d", &a2[i]);vector<int> A;A = fwt.Or(a1, a2);for (int i = 0; i < n; i++) {printf("%d%c", A[i], " \n"[i == n - 1]);}A = fwt.And(a1, a2);for (int i = 0; i < n; i++) {printf("%d%c", A[i], " \n"[i == n - 1]);}A = fwt.Xor(a1, a2);for (int i = 0; i < n; i++) {printf("%d%c", A[i], " \n"[i == n - 1]);}return 0;
}

0x20 FMT与FMI(快速莫比乌斯变换与快速莫比乌斯反演)

待更…

0x30 竞赛例题选讲

鉴于篇幅原因,我将例题详解即代码分开成一篇新的博客,链接:

【解题报告】快速沃尔什变换FWT(ICPC / CCPC / NOIP真题集)

A、(牛客练习赛41 F)简单数学题

Link

https://ac.nowcoder.com/acm/contest/373/F

Problem

定义如下函数:
f(x)={1x=1max⁡{t∣xmodt=0&&∣μ(t)∣=1}x≥2\ f(x)= \begin{cases} 1 & {x=1}\\ \max\{ t\ |\ {x \bmod t = 0}\ \&\&\ |\mu(t)| = 1 \}& {x \geq 2} \end{cases} f(x)={1max{t ∣ xmodt=0 && ∣μ(t)∣=1}​x=1x≥2​

其中μ(t)\mu(t)μ(t)为莫比乌斯函数,详见:https://en.wikipedia.org/wiki/M%C3%B6bius_function

对于任何整数x\ x x,若有 x=p1n1p2n2...pknkx = p_{1}^{n_{1}}p_{2}^{n_{2}}...p_{k}^{n_{k}}x=p1n1​​p2n2​​...pknk​​ ,其中pi\ p_{i} pi​是x\ x x 第i\ i i 大的质因子,则
g(x)=p1β(n1)p2β(n2)...pkβ(nk)g(x) = p_{1}^{\beta(n_{1})}p_{2}^{\beta(n_{2})}...p_{k}^{\beta(n_{k})}g(x)=p1β(n1​)​p2β(n2​)​...pkβ(nk​)​​

β(x)={0x is even1x is odd\beta(x)= \begin{cases} 0& \text{x is even}\\ 1& \text{x is odd} \end{cases}β(x)={01​x is evenx is odd​

现在定义F(a,b,c)=g(f(a)∗f(b)∗f(c))\ F(a, b, c) = g(f(a)*f(b)*f(c)) F(a,b,c)=g(f(a)∗f(b)∗f(c))

并给出三个长度均为n\ n n 的数列
A1A2A3...An\ A_{1}A_{2}A_{3}...A_{n} A1​A2​A3​...An​​

B1B2B3...Bn\ B_{1}B_{2}B_{3}...B_{n} B1​B2​B3​...Bn​​

C1C2C3...Cn\ C_{1}C_{2}C_{3}...C_{n} C1​C2​C3​...Cn​
对于某个整数z\ z z,如有 z=F(Ai,Bj,Ck)(1≤i,j,k≤n)\ z = F(A_{i}, B_{j}, C_{k})(1 \leq i,j,k \leq n) z=F(Ai​,Bj​,Ck​)(1≤i,j,k≤n)

则称GF(i,j,k)\ GF(i, j, k) GF(i,j,k)为z的一种表示

设S\ S S 集合为 S={z∣z=F(Ai,Bj,Ck),1≤i,j,k≤n}S = \{ z|z=F(A_{i}, B_{j}, C_{k}),1 \leq i,j,k \leq n \}S={z∣z=F(Ai​,Bj​,Ck​),1≤i,j,k≤n} ,∣Z∣\ {|Z|} ∣Z∣为 S\ S S 中元素的个数

求 ans=∑i=1∣Z∣zikians = \sum_{i=1}^{|Z|}{z_{i} k_{i}}ans=∑i=1∣Z∣​zi​ki​ ,其中 ziz_{i}zi​ 是集合S\ S S 的第i\ i i 个元素,其中 kik_{i}ki​ 为 ziz_{i}zi​ 的不同的表示的个数。答案对109+7\ 10^{9}+7 109+7 取模。

注意:对于一个数 z\ z z ,如果z=F(Ai1,Bj1,Ck1))=F(Ai2,Bj2,Ck2))\ z = F(A_{i_{1}}, B_{j_{1}}, C_{k_{1}})) = F(A_{i_{2}}, B_{j_{2}}, C_{k_{2}})) z=F(Ai1​​,Bj1​​,Ck1​​))=F(Ai2​​,Bj2​​,Ck2​​)) ,只要 i1≠i2orj1≠j2ork1≠k2i_{1}\neq i_{2}\ or\ j_{1}\neq j_{2}\ or\ k_{1}\neq \ k_{2}i1​​=i2​ or j1​​=j2​ or k1​​= k2​ ,那么我们说 zzz 的这两种表示的两种不同的表示。

1≤n≤105,Ai,Bi,Ci≤10181\le n\le 10^5,A_i,B_i,C_i\le10^{18}1≤n≤105,Ai​,Bi​,Ci​≤1018,保证后三行输入的所有整数每个数的最大质因子不会超过71\ 71 71。

Solution

A、(牛客练习赛41 F)简单数学题

B、(2018 ACM - ICPC shenyang I)Distance Between Sweethearts

Link

http://acm.hdu.edu.cn/showproblem.php?pid=6456

Problem

太长不看

给定6个不超过 2000 的整数: UIboy,UAboy,UGboyUI_{boy}, UA_{boy}, UG_{boy}UIboy​,UAboy​,UGboy​ 和 UIgirl,UAgirl,UGgirlUI_{girl}, UA_{girl}, UG_{girl}UIgirl​,UAgirl​,UGgirl​

定义 Igirl,Agirl,GgirlI_{girl}, A_{girl}, G_{girl}Igirl​,Agirl​,Ggirl​ 和 Iboy,Aboy,GboyI_{boy}, A_{boy}, G_{boy}Iboy​,Aboy​,Gboy​。

给出了以下公式来测量我的爱人和我的心之间的距离:

distance(boy,girl)=max⁡{∣Iboy−Igirl∣,∣Aboy−Agirl∣,∣Gboy−Ggirl∣}⊕Iboy⊕Aboy⊕Gboy⊕Igirl⊕Agirl⊕Ggirldistance(boy, girl) = \max\{|I_{boy} - I_{girl}|, |A_{boy} - A_{girl}|, |G_{boy} - G_{girl}|\} \oplus I_{boy} \oplus A_{boy} \oplus G_{boy} \oplus I_{girl} \oplus A_{girl} \oplus G_{girl}distance(boy,girl)=max{∣Iboy​−Igirl​∣,∣Aboy​−Agirl​∣,∣Gboy​−Ggirl​∣}⊕Iboy​⊕Aboy​⊕Gboy​⊕Igirl​⊕Agirl​⊕Ggirl​

其中maxSmax{S}maxS、∣x∣|x|∣x∣ 和 ⊕⊕⊕ 分别对应S的最大值、x的绝对值和位异或运算符。

它们满足以下限制条件:

0≤Igirl≤UIgirl,0≤Agirl≤UAgirl,0≤Ggirl≤UGgirl0 \le I_{girl} \le UI_{girl}, 0 \le A_{girl} \le UA_{girl}, 0 \le G_{girl} \le UG_{girl}0≤Igirl​≤UIgirl​,0≤Agirl​≤UAgirl​,0≤Ggirl​≤UGgirl​

0≤Iboy≤UIboy,0≤Aboy≤UAboy,0≤Gboy≤UGboy0 \le I_{boy} \le UI_{boy}, 0 \le A_{boy} \le UA_{boy}, 0 \le G_{boy} \le UG_{boy}0≤Iboy​≤UIboy​,0≤Aboy​≤UAboy​,0≤Gboy​≤UGboy​

它们的任意值在其限制条件下都可以是具有相同概率的整数。

现在我需要你的帮助来计算我们这对依然热恋的情侣的心之间距离的期望。

请你输出 (1+UIboy)(1+UAboy)(1+UGboy)(1+UIgirl)(1+UAgirl)(1+UGgirl)(1 + UI_{boy}) (1 + UA_{boy}) (1 + UG_{boy}) (1 + UI_{girl}) (1 + UA_{girl}) (1 + UG_{girl})(1+UIboy​)(1+UAboy​)(1+UGboy​)(1+UIgirl​)(1+UAgirl​)(1+UGgirl​) 与距离的期望的乘积(保证答案一定是一个整数)。

保证答案在 264−12^{64} - 1264−1 以内。

Sample Input

3
3 1 2 4 3 3
1 2 1 2 1 3
3 2 5 4 3 5

Sample Output

Case #1: 3880
Case #2: 369
Case #3: 24728

Solution

B、(2018 ACM - ICPC shenyang I)Distance Between Sweethearts

C、(2019ACM - ICPC nanchang H)Another Sequence

Problem

给出一个长度为 nnn 的序列 aia_iai​ 和另一个长度为 nnn 的序列 bib_ibi​,现在定义 cic_ici​ 的生成方式如下:

  • cic_ici​ 的长度为n2n^2n2

  • ci∗(n−1)+j=ai∣bjc_{i * (n - 1) + j} = a_i | b_jci∗(n−1)+j​=ai​∣bj​

  • 将 cic_ici​ 升序排序

现在要求支持两种操作:

  • 将 cic_ici​ 中 [l,r][l,r][l,r] 区间内的数开根
  • 询问 cxc_xcx​ 的数值。

Solution

C、(2019ACM - ICPC nanchang H)Another Sequence

D、(CROC 2016 - Final Round C)Binary Table

Link

https://codeforces.com/contest/662/problem/C

Problem

给你一个 n×mn\times mn×m 的 010101 矩阵,每次操作:你可以挑选任意的某一行或者某一列翻转( 000 变 111,111 变 000 ),然后你需要使得整个矩阵的 111 的数量尽可能少,问你最少数量是多少。

Solution

D、(CROC 2016 - Final Round C)Binary Table

E、(HAOI2015)luogu P3175 按位或

Link

https://www.luogu.com.cn/problem/P3175

Problem

刚开始你有一个数字 000,每一秒钟你会随机选择一个 [0,2n−1][0,2^n-1][0,2n−1] 的数字,与你手上的数字进行 或 操作。选择数字 iii 的概率是 pip_ipi​。保证 0≤pi≤10\leq p_i \leq 10≤pi​≤1,∑pi=1\sum p_i=1∑pi​=1。问期望多少秒后,你手上的数字变成 2n−12^n-12n−1。

Solution

E、(HAOI2015)luogu P3175 按位或

参考资料:

注,文中位运算卷积根据定义展开来证明的方法(就是那一大坨和式)参考:快速沃尔什变换(FWT) %%%

  • FWT快速沃尔什变换学习笔记
  • https://www.luogu.com.cn/blog/wangrx/solution-p-4717
  • 多项式学习笔记

《小学生都能看懂的快速沃尔什变换从入门到升天教程》(FWT / FMT / FMI)(最最严谨清晰的证明!零基础也能得学会!)相关推荐

  1. 小学生都能看懂的FFT!!!

    小学生都能看懂的FFT!!! 前言 在创新实践中心偷偷看了一天FFT资料后,我终于看懂了一点.为了给大家提供一份简单易懂的学习资料,同时也方便自己以后复习,我决定动手写这份学习笔记. 食用指南: 本篇 ...

  2. 小学生都能看懂,彻底解决环境搭建难题,一步一截图,再无VMware网络难题

    小学生都能看懂,彻底解决环境搭建难题,一步一截图,再无VMware网络难题 原创 韦东山 百问科技 1周前 上周四我们预告了这周要发布环境搭建的终极解决方案,经过一周的努力,终于写好了文档,Ubunt ...

  3. 《小学生都能看懂的三类斯特林数从入门到升天教程 》(含性质完整证明、斯特林反演、拉赫数)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 真的特别简单,我尽量讲的详细一些,本文包含了几乎所有性质定理证明,老少皆宜 ~ 内容过多,质量过硬,建 ...

  4. 《小学生都能看懂的群论从入门到升天教程》 《群论全家桶》

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 小学生都能看懂系列,小学生:我太难了   群论.置换.Bunrnside引理.Pόlya定理等概念是群 ...

  5. 《小学生都能看懂的生成函数从入门到升天教程》《生成函数全家桶》

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 小学生都能看懂系列 目录 0x00 生成函数 0x10 例题引入 0x11 ExampleA\tt E ...

  6. nxn次方求和函数_算法|小学生都能看懂的生成函数入门教程

    作者:自为风月马前卒 链接:https://ac.nowcoder.com/discuss/179728 来源:牛客网 前言 第一次当标题党真是有点不适应 现在网上讲生成函数的教程大多都是从 开始,但 ...

  7. TCP 的 3 次握手 4 次挥手,小学生都能看懂

    前几天发了一个朋友圈,发现暗恋已久的女生给我点了个赞,于是我当晚辗转反侧.彻夜未眠!想着妹子是不是对我有感觉呢?不然怎么会突然给我点赞呢?要不趁机表个白? 于是第二天我在心中模拟了多次表白的话语,连呼 ...

  8. 人人都能看懂的 Python 装饰器入门教程!

    大家好,我是菜鸟哥! 之前的文章中提到,很多人认为理解了装饰器 的概念和用法后,会觉得自己的 Python 水平有一个明显的提高. 但很多教程在一上来就会给出装饰器的定义以及基本用法,例如你一定会在很 ...

  9. 什么是分布式数据库?小学生都能看懂。

    自从互联网进入了 web2.0 时代以来,数据库作为核心的底层基础设施软件也经历了蓬勃的发展期,从早期的单机关系型数据库到NoSQL 再到如今的 NewSQL,数据库领域不管是技术还是场景都发生了巨大 ...

最新文章

  1. Mybatis-Plus一个新的报错:数据库表名与SQL的关键字冲突!!!
  2. HTML超文本描述语言,HTML超文本标记语言的介绍
  3. 500 - Internal server error.
  4. “猜画小歌”的一些细节和思考
  5. [Deep Learning]任意层cnn的matlab版本实现
  6. linux网络编程之socket:使用fork并发处理多个client的请求
  7. SAP License:SAP权限管理讲财务(二)-看懂财务报表
  8. scikit-learn 算法的通用形式
  9. linux微软公式编辑器,linux下的公式编辑器
  10. 项目管理中,如何有效地把控项目风险?
  11. 2021年胡润中国百富榜研究报告
  12. 在FPGA开发板上玩《超级玛丽》之笔记 -(2)重构2A03CPU
  13. 1.认识华为数据通信
  14. Mina中的支付交易snark
  15. MXNet -aws深度学习框架之选择
  16. 考研350什么水平计算机,考研350分的难度相当于高考考什么水平?很多人都不知道...
  17. 如何评价 Richard Stallman?
  18. 华为 PIM-SM RP选举与切换
  19. 初学Pybugthon头秃笔记(三)
  20. 呕心沥血整理,Nginx看这个就够了

热门文章

  1. 85.4% mIOU!NVIDIA:使用多尺度注意力进行语义分割,代码已开源!
  2. OpenVINO开发教程之八 – 道路分割
  3. 【项目实践】中英文文字检测与识别项目(CTPN+CRNN+CTC Loss原理讲解)
  4. MPASNET:用于视频场景中无监督深度人群分割的运动先验感知SIAMESE网络
  5. 关于如何换肤、子类化的解决方案
  6. 代码重构中的几个概念
  7. ActiveMQ死信队列使用
  8. flash绘图API :flash player11新增的绘图API方法--cubicCurveTo
  9. php读取大文件某行内容,php读取大文件最后几行数据的实现代码
  10. 北京学python去哪里好_北京想学习Python应该去哪里好