[Polynomial algorithm] (Part 4) FWT Fast Walsh Transform Learning Notes

Other polynomial algorithm Portal:

[Polynomial algorithm] (Part 1) FFT Fast Fourier Transform Learning Notes

[Polynomial algorithm] (Part 2) NTT fast number theory transformation study notes

[Polynomial algorithm] (Part 5) Divide and Conquer FFT study notes

\ (4.Extreme-FWT \)

  • FWT\((Fast\ Walsh-Hadamard\ Transform)\)

    Chinese name: Fast Walsh Transform

    (Fast Wrong-Answer Transform)


\ (Q: \) has finished poured? \ (FWT \) , then what is? We are now able to handle any situation polynomial multiplication, and also to do this?

\(A:\)I do not want to learn ah, did not back down

Although we can quickly find \ (C = A * B, C_k = \ sum_ {i + j = k} A_i * B_j \) , but now let you ask \ (C = A \ oplus B , C_k = \ sum_ {I \ Oplus J = K} A_i * B_j \) , where \ (\ Oplus \) represents a bit operation symbol such as \ (| (or), \ & (and), \ Land (XOR) \) , how do you do it?

Then he went to the \ (FWT \) debut.

Let us for a \ (FWT \) is \ (3 \) formsEmotional understandingDiscuss


\ (Part1 - FWT (or) \)

Set \ (A_0, A_1 \) respectively of length \ (n = 2 ^ x \ ) polynomial \ (A \) of the front and rear halves.

Firstly, \ (FWT (A) \) is calculated:

\[ FWT(A)=\begin{cases} (FWT(A_0),FWT(A_0)+FWT(A_1))&(n>1)\\ A&(n=1) \end{cases} \]

Wherein \ ((A, B) \ ) represents a two polynomials are connected.

So \ (n = 1 \) it is clearly right, border thing.

As \ (n> 1 \) How to understand the situation?

For \ (A_0 \) and \ (A_0 \) in two subscripts \ (or \) up a little still \ (A_0 \) in (the highest bit is binary \ (0 \) , is the first half), then contribute to the first half only.

For \ (A_1 \) and \ (A_1 \) in two numbers, empathy only contribute to the second half.

For \ (A_0 \) and \ (A_1 \) two numbers, thinking \ (FWT (A) _k \ ) sense, are:

\[FWT(A)_k=\sum_{i|k=k}A_i\]

Because when \ (i | k = k, j | k = k \) when there is \ ((I | J) | K = K \) , satisfies \ (the FWT \) may be combined properties.

Since then \ (A_1 \) subscript binary MSB is \ (1 \) , so \ (or \) together generated only contribution to the second half.

Contribution is \ (A_0 \) to \ (A_1 \) contribution ( \ (A_1 \) has contributed over yourself, do not add).

Then the formula is quite clear.

Meanwhile The \ (FWT (A) \) meaning easily find \ (the FWT (A_0 A_1 +) = the FWT (A_0) + the FWT (A_1) \) .

Then prove \ (FWT (A | B) = FWT (A) * FWT (B) \) (guarantee \ (or \) correctness convolution answer, or else \ (FWT \) there is no use).

When \ (n = 1 \) , the property is clearly established

When \ (n> 1 \) when:

\[ \begin{equation} \begin{split} FWT(A|B)=&FWT((A|B)_0,(A|B)_1)\\ &=FWT(A_0|B_0,A_0|B_1+A_1|B_0+A_1|B_1)\\ &=(FWT(A_0|B_0),FWT(A_0|B_0+A_0|B_1+A_1|B_0+A_1|B_1))\\ &=(FWT(A_0)*FWT(B_0),FWT(A_0)*FWT(B_0)+FWT(A_0)*FWT(B_1)\\ &+FWT(A_1)*FWT(B_0)+FWT(A_1)*FWT(B_1))\\ &=(FWT(A_0)*FWT(B_0),(FWT(A_0)+FWT(A_1))*(FWT(B_0)+FWT(B_1)))\\ &=(FWT(A_0)*FWT(B_0),FWT(A_0+A_1)*FWT(B_0+B_1)))\\ &=(FWT(A_0),FWT(A_0+A_1))*(FWT(B_0),FWT(B_0+B_1))\\ &=FWT(A)*FWT(B) \end{split} \end{equation} \]

That the mathematical induction, this property holds.

So \ (or \) is \ (FWT \) is very good ~ ~ wrote the code behind.

\(Part2--FWT(and)\)

\ (and \) of \ (FWT \) on and \ (or \) is very similar to the.

Since \ (A_0 \) and (A_1 \) \ highest bit different, so \ (and \) after only (A_0 \) \ contribute.

Similar \ (or \) can be obtained \ (FWT (A) \) is calculated:

\[ FWT(A)=\begin{cases} (FWT(A_0)+FWT(A_1),FWT(A_1))&(n>0)\\ A(n=0) \end{cases} \]

As proved not write, and (or \) \ similar,Says trouble

\ (Part3 - FWT (xor) \)

mostfanThe \ (xor \) to the

To be honest, the Internet to find a lot of \ (Blog \) , do not seem to give construction method,Then I will not ah

When you are looking for someone fairy her laws

The first is \ (FWT (A) \) is calculated:

\[ FWT(A)=\begin{cases} (FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))&(n>0)\\ A(n=0) \end{cases} \]

Look at all sick, How it's constructed ah \ (QAQ \)

So, by definition, is easy to prove \ (FWT (A \ pm B ) = FWT (A) \ pm FWT (B) \)

Since \ (the FWT \) is a linear combination, to satisfy the above properties.

Then \ (FWT (A \ land B ) = FWT (A) * FWT (B) \)

This can be proved by mathematical induction,See References


\ (Q: \) and so on ...... is not what's missing? \ (FWT \) how to change it back later?

\(A:\)This is not simpleThe next process is the \ (IFWT \) up!

\(Part4--IFWT(or)\)

\ (Emm ... \) As \ (IFWT \) it is very simple, you can reverse the conversion.

(Is not this nonsensical)

Then for \ (or \) is \ (IFWT \) , there is before you consider \ (FWT \) equation:

\ [FWT (A) = (FWT (A_0), FWT (A_0) + FWT (A_1)) \]

That is:

\ [FWT (A) _0 = FWT (A_0), FWT (A) _1 = FWT (A_0) + FWT (A_1) \]

\ [FWT (A_0) = FWT (A) _0, FWT (A_1) = FWT (A_0) -FWT (A) _1 = FWT (A) _0-FWT (A) _1 \]

At this time, the definition of \ (IFWT (A) _0 = the FWT (A_0), IFWT (A) the FWT _1 = (A_1) \) , has:

\[ IFWT(A)=\begin{cases} (IFWT(A_0),IFWT(A_0)-IFWT(A_1))&(n>0)\\ A&(n=0) \end{cases} \]

\ (En ... \) really simple

\(Part5--IFWT(and)\)

Similar \ (or \) is \ (IFWT \) , can be obtained directly:

\[ IFWT(A)=\begin{cases} (IFWT(A_0)-IFWT(A_1),IFWT(A_1))&(n>0)\\ A(n=0) \end{cases} \]

Similar to the process here is not to repeat them. .

\ (Part IFWT (chorus) \)

\ (xor \) is \ (IFWT \) as simple as a surprise.

By definition was:

\ [\ Begin {cases} FWT (A) _0 = FWT (A_0) + FWT (A_1) \\ FWT (A) _1 = FWT (A_0) -FWT (A_1) \ end {cases} \]

Solution of the equation is simple.

Finally there is:

\[ IFWT(A)=\begin{cases} (\frac{IFWT(A_0)+IFWT(A_1)}2,\frac{IFWT(A_0)-IFWT(A_1)}2)&(n>0)\\ A&(n=0) \end{cases} \]

Finally finished


Then the next step isFigure write wordsSee the definition of a process to write the code:

Here in order to save the amount of codes \ (6 \) functions written together (because substantially similar frame).

P4717 [template] Fast Walsh Transform

Code:

#include <cstdio>
#include <cstring>
typedef long long ll;

const int Mod=998244353,Inv2=(Mod+1)>>1;//Inv2 2在mod998244353下的逆元
int n,a[1<<17],b[1<<17],as[1<<17],bs[1<<17];

void FWT(int *A,int op,int t)
//op [1/-1][FWT/IFWT]
//t [1,2,3][or/and/xor]
{
    for(int i=2;i<=n;i<<=1)//i 区间长度
        for(int j=0,m=i>>1;j<n;j+=i)//j 区间左端 m 区间大小一半
            for(int k=0;k<m;++k)//k 正在算第几个数
                if(t==1)A[j+m+k]=((ll)A[j+m+k]+A[j+k]*op+Mod)%Mod;
                else if(t==2)A[j+k]=((ll)A[j+k]+A[j+m+k]*op+Mod)%Mod;
                else
                {
                    int A0=A[j+k],A1=A[j+m+k];
                    A[j+k]=(ll)(A0+A1)*(op==1?1:Inv2)%Mod;
                    A[j+m+k]=(ll)(A0-A1+Mod)*(op==1?1:Inv2)%Mod;
                }
}

int main()
{
    scanf("%d",&n),n=1<<n;
    for(int i=0;i<n;++i)scanf("%d",&as[i]);
    for(int i=0;i<n;++i)scanf("%d",&bs[i]);
    for(int t=1;t<=3;++t)//分别计算or/and/xor
    {
        memcpy(a,as,sizeof(int)*n);
        memcpy(b,bs,sizeof(int)*n);
        FWT(a,1,t),FWT(b,1,t);
        for(int i=0;i<n;++i)a[i]=a[i]*1LL*b[i]%Mod;
        FWT(a,-1,t);
        for(int i=0;i<n;++i)printf("%d%c",a[i],i==n-1?'\n':' ');
    }
    return 0;
}

Code should be easy to understand, not explained.

I can only say: \ (FWT \)Nice backNice write.

References :( \ (Dalao \ TQL \) )

FWT Fast Walsh Transform Study Notes - Small konjac yyb

A little learning and thinking about the Fast Walsh Transform (FWT) of -ACMLCZH

Guess you like

Origin www.cnblogs.com/LanrTabe/p/11305626.html