快速沃尔什变换FWT

大概在做CC月赛的时候看到了这样一道题:https://www.codechef.com/OCT17/problems/XORTREEH
题意是要你做一个%330301441的类似FWT的东西。定义数组A,B,C。定义一个操作 AB=C

C[i]=uvA[u]B[v]  |  u,vki  k=2,3,4,...,9,10

要你求一个 P=AA...AXA
当k=2时,这是一个异或规则的FWT。
接下来考虑k=2的情况。假设ABC长度为2的幂次,用 Ai 表示最高位为i的一段A。
C0=A0B0+A1B1C1=A0B1+A1B0(C0,C1)=(A0B0+A1B1,A0B1+A1B0)

然后就在这里卡住了。。

然后去网上搜FWT,又听某dalao讲了,大概知道了一些思路。
构造一个 trans(A)=(trans(A0+A1),trans(A0A1)) ,以及逆变换 trans(A)=(trans(A0+A12),trans(A0A12))
然后有

trans(C)=trans(A)×trans(B)

这里的 A×B=C 代表 C[i]=A[i]B[i]
C=AB=trans(trans(C))=trans(trans(A)×trans(B))
然后如果是多个相乘就是

D=ABC=trans(trans(A)×trans(B)×trans(C))

这里的 trans trans 操作都可以在 O(nlogn) 的时间内完成,所以总复杂度为 O(nlogn)

然后考虑k更大的情况,根据刚才的方法,我们需要一个能够在较低复杂度内实现的 transk 和他的逆变换 transk

进行一些枚举,可以构造 trans(A)=(trans(A0+A1+A2),trans(A0+wA1+w2A2),trans(A0+w2A1+w4A2)) 。其中 w3=1

这时发现这个模数很牛逼啊,他保证了我存在 w 使wk=1

然后推广一波,好像很棒啊!复杂度大概是 O(knlogkn) ?

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页