FWT,FMT,FST,k进制FWT

二进制位运算

常见的二进制位运算有:或,与,异或。分别对应了FMT,FMT与FWT。
下面从易到难介绍这几种运算。一下默认幂级数长度为 2 n 2^n 2n

FMT

快速莫比乌斯变化,定义也挺简单的。 f ( S ) = ∑ T ⊂ S g ( T ) f(S) = \sum_{T\subset S} g(T) f(S)=TSg(T)
实际上就是子集和,同理定义快速莫比乌斯反演,即将快速莫比乌斯变化反演即可 f ^ ( S ) = ∑ T ⊂ S ( − 1 ) ∣ S ∣ − ∣ T ∣ g ( T ) \hat{f}(S) = \sum_{T\subset S} (-1)^{|S| - |T|}g(T) f^(S)=TS(1)STg(T)
然后或卷积就明显可以通过此来优化。
同理就是与卷积。
定义是超集,反之亦然。

FWT

特别解决异或运算的。之后与 k k k进制 F W T FWT FWT一起写。

FST

就是failed system test
子集卷积。如果单纯做一个或卷积,那么势必答案是不对的,因为要求的条件实际上是

i | j == k && i & j == 0

而或卷积仅仅满足了第一个条件。那么多记一维表示应当有多少个即可。

k进制FWT

k进制下的异或任然是不进位加法,假设符号任然是 ⊕ \oplus ,并且是数组A * B = C。
从原理上讲,正变换是我们要做的事情是找到这样一个矩阵 w w w,使得原数组左乘上这个矩阵后还满足A * B = C。
逆变换是左乘这个矩阵的逆矩阵。那么考虑是什么意思
∑ i ⊕ j = k A i ∗ B j ∗ w ( x , i ) ∗ w ( x , j ) = C k ∗ w ( x , k ) \sum \limits_{i \oplus j = k} A_i * B_j * w(x, i) * w(x, j) = C_k * w(x, k) ij=kAiBjw(x,i)w(x,j)=Ckw(x,k)
对比系数可知
w ( x , i ) ∗ w ( x , j ) = w ( x , k )    ( i ⊕ j = k ) w(x, i) * w(x, j) = w(x, k) \;(i \oplus j = k) w(x,i)w(x,j)=w(x,k)(ij=k)
那么我们的目的即使找到这样的一个矩阵。
那么这样的性质让我们想到单位根: w k i ∗ w k j = w k i ⊕ j w_{k}^{i} * w_{k}^{j}=w_{k}^{i\oplus j} wkiwkj=wkij。从而联想到范德蒙德矩阵
[ 1 1 1 . . . 1 1 w k 1 w k 2 . . . w k k − 1 1 w k 2 w k 4 . . . w k 2 ( k − 1 ) . . . . . . . . . . . . . . . 1 w k k − 1 w k 2 ( k − 1 ) . . . w k ( k − 1 ) ( k − 1 ) ] \begin{bmatrix} 1& 1 & 1& ... & 1\\ 1& w_k^1& w_k^2& ... & w_k^{k - 1}\\ 1& w_k^2 & w_k^4& ... & w_k^{2(k - 1)}\\ ...& ...& ...& ...& ...\\ 1& w_k^{k - 1}& w_k^{2(k - 1)} & ... & w_k^{(k - 1)(k - 1)} \end{bmatrix} 111...11wk1wk2...wkk11wk2wk4...wk2(k1)...............1wkk1wk2(k1)...wk(k1)(k1)
然后我们也知道其逆矩阵
1 k [ 1 1 1 . . . 1 1 w k − 1 w k − 2 . . . w k − ( k − 1 ) 1 w k − 2 w k − 4 . . . w k − 2 ( k − 1 ) . . . . . . . . . . . . . . . 1 w k − ( k − 1 ) w k − 2 ( k − 1 ) . . . w k − ( k − 1 ) ( k − 1 ) ] \frac{1}{k} \begin{bmatrix} 1& 1 & 1& ... & 1\\ 1& w_k^{-1}& w_k^{-2}& ... & w_k^{-(k - 1)}\\ 1& w_k^{-2} & w_k^{-4}& ... & w_k^{-2(k - 1)}\\ ...& ...& ...& ...& ...\\ 1& w_k^{-(k - 1)}& w_k^{-2(k - 1)} & ... & w_k^{-(k - 1)(k - 1)} \end{bmatrix} k1111...11wk1wk2...wk(k1)1wk2wk4...wk2(k1)...............1wk(k1)wk2(k1)...wk(k1)(k1)
然后不就完了?剩下的与正常的FWT一样的。就是答案由len / k的答案组合而来。同时要注意,如果是mod一个NTT质数的时候,有 w n 0 = g m o d − 1 n w_n^0 = g^{\frac{mod - 1}{n}} wn0=gnmod1
下面贴一份代码:

int wn[k];
inline int w(int x, int y) { return wn[(x * y) % k]; }

void FWT(int *a, int len, int coef) {
    static int b[k];
    int v;

    for (int i = 1; i < len; i *= k) {
        for (int j = 0; j < len; j += i * k) {
            for (int k = j; k < j + i; k++) {
                for (int d = 0; d < k; d++) {
                    b[d] = a[k + d * i];
                    a[k + d * i] = 0;
                }

                for (int d = 0; d < k; d++) {
                    v = k + d * i;
                    for (int _d = 0; _d < 4; _d++) {
                        a[v] = add(a[v], 1ll * w(d, coef * _d) * b[_d] % mod);
                    }
                }
            }
        }
    }

    if (coef == -1) {
        int Inv = qpow(len, mod - 2);
        for (int i = 0; i < len; i++) a[i] = 1ll * Inv * a[i] % mod;
    }
}

其中 w n [ i ] = ( g m o d − 1 k ) i wn[i] = (g^{\frac{mod - 1}{k}})^{i} wn[i]=(gkmod1)i c o e f coef coef 1 1 1时为正变换, − 1 -1 1时为逆变换。

你可能感兴趣的:(总结,省选,矩阵与行列式)