位运算卷积
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了
以上是关于位运算卷积的主要内容,如果未能解决你的问题,请参考以下文章