位运算卷积

Posted cjoiershiina-mashiro

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了位运算卷积相关的知识,希望对你有一定的参考价值。

FWT

用来解决(f(k)=sumlimits_{i?j=k}g(i)*h(j))

本质思想与FFT是一样的,就是构造一个函数的“点值表达”,然后直接对“点值表达”做位运算卷积,然后再表示回来。

(?=operatorname{and})

利用性质(ioperatorname{and}k=kwedge joperatorname{and}k=kLeftrightarrow (ioperatorname{and}j)operatorname{and}k=k)
构造(F(i)=sumlimits_{joperatorname{and}i=i}f(j))(G,H)同理。
(G(k)H(k)=sumlimits_{ioperatorname{and}k=k}g(i)sumlimits_{joperatorname{and}k=k}h(j))
(=sumlimits_{ioperatorname{and}joperatorname{and}k=k}g(i)h(j))
(=sumlimits_{ioperatorname{and}k=k}f(i)=F(k))
因此我们可以先由(g,h)得到(G,H),然后计算(F),再得到(f)

那么我们的问题就变成了如何快速变换。
从低位往高位考虑,每一次遍历整个序列,把当前位为(1)的值加到其它位相同且当前位为(0)的值上去。
逆变换就是减。

(?=operatorname{or})

利用性质(ioperatorname{or}k=kwedge joperatorname{or}k=kLeftrightarrow (ioperatorname{or}j)operatorname{or}k=k)
构造(F(i)=sumlimits_{joperatorname{or}i=i}f(j))(G,H)同理。
(G(k)H(k))
(=sumlimits_{ioperatorname{or}k=k}g(i)sumlimits_{joperatorname{or}k=k}h(j))
(=sumlimits_{ioperatorname{or}joperatorname{or}k=k}g(i)h(j)=sumlimits_{ioperatorname{or}k=k}f(i)=F(k))
因此我们可以先由(g,h)得到(G,H),然后计算(F),再得到(f)

那么我们的问题就变成了如何快速变换。
从低位往高位考虑,每一次遍历整个序列,把当前位为(0)的值加到其它位相同且当前位为(1)的值上去。
逆变换就是减。

(?=operatorname{xor})

(operatorname{bit}(x))(x)的二进制数位和的奇偶性。
利用性质(operatorname{bit}(ioperatorname{and}k)operatorname{xor}operatorname{bit}(joperatorname{and}k)=operatorname{bit}((ioperatorname{xor}j)operatorname{and}k))
构造(F(i)=sumlimits_j(-1)^{operatorname{bit}(ioperatorname{and}j)}f(j))(G,H)同理。
(G(k)H(k)=sumlimits_i(-1)^{operatorname{bit}(ioperatorname{and}k)}g(i)sumlimits_j(-1)^{operatorname{bit}(joperatorname{and}k)}h(j))
(=sumlimits_{i,j}(-1)^{operatorname{bit}((ioperatorname{xor}j)operatorname{and}k)}g(i)h(j))
(=sumlimits_t(-1)^{operatorname{bit}(toperatorname{and}k)}sumlimits_{ioperatorname{xor}j=t}g(i)h(j))
(=sumlimits_t(-1)^{operatorname{bit}(toperatorname{and}k)}f(t)=F(k))
因此我们可以先由(g,h)得到(G,H),然后计算(F),再得到(f)

那么我们的问题就变成了如何快速变换。
从低位往高位考虑,每一次遍历整个序列,当前位为(0)的下标为(i),其它位相同且当前位为(1)的下标为(j),那么(A_i=a_i+a_j,A_j=a_i-b_j)
逆变换就是(a_i=frac{A_i+A_j}2,a_j=frac{A_i-A_j}2)

FST

(f(S)=sumlimits_{Tsubseteq S}g(T)h(Ssetminus T))

现在有两个要求所以FWT不能直接做。我们把这个东西变成二维的。
(f(S,i)=sumlimits_{j=1}^isumlimits_{Acup B=S}g(A,j)h(B,i-j))
其中(f(S,i) e0Rightarrow i=|S|)
(F(i,S)=sumlimits_{Toperatorname{or}S=S}f(i,T))(G,H)同理。
那么我们可以得到(F(k)=sumlimits_{i+j=k}G(i)H(j))
因此我们可以先由(g,h)得到(G,H),然后暴力计算(F),再得到(f)
最后答案就是(f(U,|U|))
复杂度为(O(2^nn^2))别想着FFT了

以上是关于位运算卷积的主要内容,如果未能解决你的问题,请参考以下文章

FWT,FST入门

「总结」多项式生成函数相关

基于INTEL FPGA硬浮点DSP实现卷积运算

FWT 等总结

2023.4.7模板快速沃尔什变换FWT

JS位运算异常(位运算精度丢失)的原因探究