FWT学习笔记

1|0FWT

FWT 即位运算卷积,用来快速计算形如 ij=kfigj,其中 表示某种位运算。

设 FWT(A) 是幂级数 A经过 FWT 变换之后得到的幂级数。

我们需要令其满足 : AB=CFWT(A)·FWT(B)=FWT(C)(点积)。

FFT 是一个线性变换,我们也希望 FWT 变换是线性的。

我们还不知道怎么变换,于是设 c(i,j) 为变换系数,即 A[j]FWT(A)[i] 的贡献系数。

FWT(A)[i]=j=0n1c(i,j)Aj

FWT(A)FWT(B)=FWT(C),得到:

FWT(A)[i]FWT(B)[i]=FWT(C)[i]

j=0n1c(i,j)A[j]k=0n1c(i,k)B[k]=p=0n1c(i,p)C[p]

j=0n1k=0n1c(i,j)c(i,k)A[j]B[k]=p=0n1c(i,p)C[p]

根据 AB=C 得到:

C[p]=t1t2=pA[t1]B[t2]

p=0n1c(i,p)C[p]=p=0n1c(i,p)t1t2=pA[t1]B[t2]

j=0n1k=0n1c(i,j)c(i,k)A[j]B[k]=p=0n1c(i,p)t1t2=pA[t1]B[t2]

j=0n1k=0n1c(i,j)c(i,k)A[j]B[k]=p=0n1t1t2=pA[t1]B[t2]c(i,t1t2)=t1=0n1t2=0n1A[t1]B[t2]c(i,t1t2)

对比左右两边,我们发现只要满足 c(i,k)c(i,k)=c(i,jk) 就好了

现在,假设有了符合要求的 c,如何优化FWT呢?

我们把 FWT(A)[i]=j=0n1c(i,j)A[j] 按位折半,有
=j=0n21c(i,j)A[j]+j=n2n1c(i,j)A[j]i
i 去掉最高位的数字,那么有
j=0n21c(i0,j0)c(i,j)A[j]+j=n2n1c(i0,j0)c(i,j)A[j]

=c(i0,0)j=0n21c(i,j)A[j]+c(i0,1)j=n2n1c(i,j)A[j]

再设 A0 下标首位为 0 的部分,如果 i0=0,则有:

FWT(A)[i]=c(0,0)FWT(A0)[i]+c(0,1)FWT(A1)[i](i[0,n2))

如果 i0=1,则有

FWT(A)[i+n2]=c(1,0)FWT(A0)[i]+c(1,1)FWT(A1)[i](i[0,n2))

这就变成了一个规模为 n2 的子问题。

因此关键就是 c 矩阵。

1|0Or卷积

c=[1011],c1=[1011]

即:

FWT(A)[i]=FWT(A0)[i],FWT(A)[i+n2]=FWT(A0)[i]+FWT(A1)[i]

IFWT(A)[i]=IFWT(A0)[i],IFWT(A)[i+n2]=IFWT(A1)[i]IFWT(A0)[i]

1|0And卷积

c=[1101],c1=[1101]

即:
FWT(A)[i]=FWT(A0)[i]+FWT(A1)[i],FWT(A)[i+n2]=FWT(A1)[i]
IFWT(A)[i]=IFWT(A0)[i]IFWT(A1)[i],IFWT(A)[i+n2]=IFWT(A1)[i]

1|0Xor卷积

c=[1111],c1=[0.50.50.50.5]

即:
FWT(A)[i]=FWT(A0)[i]+FWT(A1)[i],FWT(A)[i+n2]=FWT(A0)[i]FWT(A1)[i]
IFWT(A)[i]=0.5IFWT(A0)[i]+0.5IFWT(A1)[i],IFWT(A)[i+n2]=0.5IFWT(A0)[i]0.5IFWT(A0)[i]

1|1CF850E Random Elections

题意:有3个候选人和 n 个投票的人,每个人对三个人的支持度排序,候选人之间两两比赛,每次比赛时,第 i 个人对哪个人更支持哪个就是1,否则是0,有函数 f,会把这 n 个01变成0或1,1就是赢,否则是输,求有多少种方案使得有个人赢了两场。

思路:首先,哪个人赢了两场是不重要的,于是可以钦定 a 赢了两场,最后再乘3。a和 b,c 在第 i 个人处有 4 种情况,其中 bi=ci 的情况有两种,于是可以枚举 bi!=ci 求方案数,再乘上 2nppc(S)。发现剩下的情况就是先令 gk=ij=kfifj,然后有 ans=i=02ngi2nppc(i),可以直接用 FWT。复杂度 O(n2n)

1|2P3175 [HAOI2015] 按位或

题意:刚开始你有一个数字 0,每一秒钟你会随机选择一个 [0,2n1] 的数字,与你手上的数字进行或(C++,C 的 |,pascal 的 or)操作。选择数字 i 的概率是 pi。保证 0pi1pi=1 。问期望多少秒后,你手上的数字变成 2n1

思路:首先用 min-max 容斥,设 Emax(S) 为遍历 S 中所有元素的最晚时间,那么 Emax(S)=TS(1)|T|+1Emin(T)

考虑怎么求 Emin(S)。根据期望的定义,有 Emin(S)=i=1i[Pmin(S)=i],而 Pmin(S)=(TS=P(T))i1(1TS=P(T)),于是有 Emin(S)=11TS=P(T)=11TUSP(T)

现在的问题就是求子集和。可以直接用 FWT 解决。

1|3Binary Table

题意:有一个 nm 列的表格,每个元素都是 0/1 ,每次操作可以选择一行或一列,把 0/1 翻转,即把 0 换为 1 ,把 1 换为 0 。请问经过若干次操作后,表格中最少有多少个 1

思路:考虑枚举翻转了哪些行,记 F(S) 表示 S 翻转后最少的 1 个数,那么 S 的答案就是 F(STi)

考虑枚举 Yi=STi,那么就是 iY[Y=TiS]F(Y),记 cnt(Y) 表示有多少列是 Y,那么就是 TY[Y=ST]F(Y)cnt(T)=TY[TY=S]F(Y)cnt(T),发现这就是异或卷积,于是可以直接 FWT。

1|4子集卷积

子集卷积是指对于给定序列 a,b,求出 ci=j|i=k,j&k=0aj×bk

对于第一个限制可以直接 OR 卷积,但是现在有了第二个限制,就不那么好做了。

但是因为对于 i&j=0,有 popcount(i)+popcount(j)=popcount(i|j),于是我们可以记

fi,j={ajpopcount(j)=i0popcount(j)i,gi,j={bjpopcount(j)=i0popcount(j)i

把 f 和 g 用 OR 卷积卷起来得到 h,然后 hpopcount(i),i 就是答案。

1|5CF1034E Little C Loves 3 III

题意:有两个序列 a,b,要求对每个 i 求出 j|k=i,j&k=0ajbk,答案对 4 取模。

思路:容易想到子集卷积,复杂度是 O(nlog2n)

考虑能否用上对 4 取模的条件。

ppc(x)=popcount(x),那么我们令 aiai×4ppc(i),bibi×4ppc(i),把 a,b 用 OR 卷积卷起来得到 c,再令 cici4ppc(i) 就是答案。

为什么这样做是对的呢?假设 i&j=0,那么 4ppc(i)×4ppc(j)4ppc(i|j)=1,而当 i&j0 时,上式就是 4 的正整数次幂,再对 4 取模就没有贡献了,因此这样做是对的。

复杂度 O(nlogn)


__EOF__

本文作者Xttttr
本文链接https://www.cnblogs.com/Xttttr/p/18014360.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Xttttr  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示