• 【洛谷4717】【模板】快速沃尔什变换


    点此看题面

    大致题意: 有两个长度为(2^n)的数组(A,B),且(C_i=sum_{j⊕k==i}A_jB_k)分别求出当(⊕)(or,and,xor)时的(C)数组。

    (FWT)

    这是一道(FWT)的板子题。

    由于(FWT)太难了,所以我只会背板子甚至连板子都不会背)。

    可见代码。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N (1<<17)
    #define X 998244353
    #define Inc(x,y) ((x+=(y))>=X&&(x-=X))
    #define Dec(x,y) ((x-=(y))<0&&(x+=X))
    #define XSum(x,y) ((x)+(y)>=X?(x)+(y)-X:(x)+(y))
    #define XSub(x,y) ((x)-(y)<0?(x)-(y)+X:(x)-(y))
    using namespace std;
    int n,a[(N<<1)+5],b[(N<<1)+5],s1[(N<<1)+5],s2[(N<<1)+5];
    class FastIO
    {
        private:
            #define FS 100000
            #define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
            #define pc(c) (C^FS?FO[C++]=c:(fwrite(FO,1,C,stdout),FO[(C=0)++]=c))
            #define tn(x) (x<<3)+(x<<1)
            #define D isdigit(c=tc())
            int T,C;char c,*A,*B,FI[FS],FO[FS],S[FS];
        public:
            I FastIO() {A=B=FI;}
            Tp I void read(Ty& x) {x=0;W(!D);W(x=tn(x)+(c&15),D);}
            Tp I void write(Ty x) {W(S[++T]=x%10+48,x/=10);W(T) pc(S[T--]);}
            Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
            I void writec(Con char& x) {pc(x);}
            I void clear() {fwrite(FO,1,C,stdout),C=0;}
    }F;
    class FWT//FWT模板
    {
        private:
            static const int SZ=N;int P,L;
            I void TransformOr(int* s,CI op)//or
            {
                for(RI i=1,j,k;i^P;i<<=1) for(j=0;j^P;j+=(i<<1)) 
                    for(k=0;k^i;++k) ~op?Inc(s[i+j+k],s[j+k]):Dec(s[i+j+k],s[j+k]);
            }
            I void TransformAnd(int* s,CI op)//and
            {
                for(RI i=1,j,k;i^P;i<<=1) for(j=0;j^P;j+=(i<<1))
                    for(k=0;k^i;++k) ~op?Inc(s[j+k],s[i+j+k]):Dec(s[j+k],s[i+j+k]);
            }
            I void TransformXor(int* s,CI op)//xor
            {
                for(RI i=1,j,k,tx,ty;i^P;i<<=1) for(j=0;j^P;j+=(i<<1)) for(k=0;k^i;++k)
                {
                    tx=s[j+k],ty=s[i+j+k],s[j+k]=XSum(tx,ty),s[i+j+k]=XSub(tx,ty),
                    !~op&&(s[j+k]=1LL*s[j+k]*(X+1>>1)%X,s[i+j+k]=1LL*s[i+j+k]*(X+1>>1)%X);
                }
            }
        public:
            I void Or(CI n,CI m,int* a,int* b)//处理or的情况
            {
                RI i,t=max(n,m);P=1,L=0;W(P<t) P<<=1,++L;
                for(TransformOr(a,1),TransformOr(b,1),i=0;i^P;++i) a[i]=1LL*a[i]*b[i]%X;
                TransformOr(a,-1);
            }
            I void And(CI n,CI m,int* a,int* b)//处理and的情况
            {
                RI i,t=max(n,m);P=1,L=0;W(P<t) P<<=1,++L;
                for(TransformAnd(a,1),TransformAnd(b,1),i=0;i^P;++i) a[i]=1LL*a[i]*b[i]%X;
                TransformAnd(a,-1);
            }
            I void Xor(CI n,CI m,int* a,int* b)//处理xor的情况
            {
                RI i,t=max(n,m);P=1,L=0;W(P<t) P<<=1,++L;
                for(TransformXor(a,1),TransformXor(b,1),i=0;i^P;++i) a[i]=1LL*a[i]*b[i]%X;
                TransformXor(a,-1);
            }
    }FWT;
    int main()
    {
        RI i,l;for(F.read(n),n=1<<n,i=0;i^n;++i) F.read(a[i]);for(i=0;i^n;++i) F.read(b[i]);
        for(i=0;i^n;++i) s1[i]=a[i],s2[i]=b[i];for(FWT.Or(n,n,s1,s2),i=0;i^n;++i) F.write(s1[i]),F.writec(' ');F.writec('
    ');
        for(i=0;i^n;++i) s1[i]=a[i],s2[i]=b[i];for(FWT.And(n,n,s1,s2),i=0;i^n;++i) F.write(s1[i]),F.writec(' ');F.writec('
    ');
        for(i=0;i^n;++i) s1[i]=a[i],s2[i]=b[i];for(FWT.Xor(n,n,s1,s2),i=0;i^n;++i) F.write(s1[i]),F.writec(' ');F.writec('
    ');
        return F.clear(),0;
    }
    
  • 相关阅读:
    修改图片大小 分辨率
    Tools
    写log
    4Sum
    3Sum Closest
    避免调试时加载符号
    SDN期末作业——负载均衡
    SDN第五次上机作业
    个人作业——软件工程实践总结作业
    SDN第四次作业
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/FWT.html
Copyright © 2020-2023  润新知