• 关于fwt的一些东西


    https://codeforces.ml/gym/102956

    这道题是要实现每一位自定义二进制下运算的fwt$A*B=C$ (*是卷积)

    跟一般fwt相同,实现过程可以按位进行

    考虑构造成$T1A*T2B=T3C$ (*是对应相乘)

    将其按照最高位拆开之后,即$A=[A0,A1],B=[B0,B1],C=[C0,C1]$

    即要求$T1A(x)*T2B(x)=T3C(x)$

     $sum_{i=1}^{2}T1[x][i]*A[i] * sum_{j=1}^{2}T2[x][j]*B[j]= sum_{k=1}^{2}T3[x][k]*C[k]$

    所以即要求$T1[x][i]*T2[x][j]=T3[x][k](i otimes j=k)$

    所以只需要找到满足的T1,T2,T3即可以实现,另外要保证T3一定是可逆的,即行列式>0

    //#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
    
    //#include <immintrin.h>
    //#include <emmintrin.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define ll long long
    #define me(x) memset(x,0,sizeof(x))
    #define IL inline
    #define rint register int
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T>void maxa(T &x,T y)
    {
        if (y>x) x=y;
    }
    template<class T>void mina(T &x,T y)
    {
        if (y<x) x=y;
    }
    template<class T>void read(T &x)
    {
        int f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
        while(c=gc(),c>47&&c<58) x=x*10+(c^48); x*=f;
    }
    const int maxn=1000000;
    struct cp {
        ll x,y;
        cp operator +(cp B)
        {
            return (cp){x+B.x,y+B.y};
        }
        cp operator -(cp B)
        {
            return (cp){x-B.x,y-B.y};
        }
        ll operator *(cp B)
        {
            return x*B.y-y*B.x;
        }
        int half() { return y < 0 || (y == 0 && x < 0); }
    };
    ll aa[20][2][2],bb[20][2][2],cc[20][2][2],ah[20][2][2],bh[20][2][2],ch[20][2][2];
    char s[30][6];
    int h[30],p[30];
    void gao()
    {
        rep(i,0,15)
        {
            rep(j,0,81*81*81-1)
            {
                int a[2][2],b[2][2],c[2][2];
                me(a); me(b); me(c);
                int k=j%81;
                rep(i1,0,1)
                {
                  rep(j1,0,1)
                  {
                      a[i1][j1]=k%3-1;
                      k/=3;
                  }
                }
                k=(j/81)%81;
                rep(i1,0,1)
                {
                  rep(j1,0,1)
                  {
                      b[i1][j1]=k%3-1;
                      k/=3;
                  }
                }
                k=(j/81)/81;
                rep(i1,0,1)
                {
                  rep(j1,0,1)
                  {
                      c[i1][j1]=k%3-1;
                      k/=3;
                  }
                }
                bool tt=1;
                rep(i1,0,1)
                {
                  int cc=0;
                  rep(j1,0,1)
                    rep(k1,0,1)
                    {
                      if (c[i1][(i>>cc)&1]!=a[i1][j1]*b[i1][k1]) tt=0;
                      cc++;
                    } 
                }
                if (!tt) continue;
                int t=c[0][0]*c[1][1]-c[1][0]*c[0][1];
                if (t)
                {
                    h[i]=t;
                    c[0][1]*=-1; c[1][0]*=-1;
                    swap(c[0][0],c[1][1]);
                    rep(i1,0,1)
                      rep(j1,0,1)
                      {
                        aa[i][i1][j1]=a[i1][j1];
                        bb[i][i1][j1]=b[i1][j1];
                        cc[i][i1][j1]=c[i1][j1];
                      }
                    break;
                }
            }
        }
    }
    int n,m;
    void fwt(ll *a,ll b[20][2][2])
    {
        int gg=0;
        for (int i=1;i<m;i*=2,gg++)
          for (int j=0;j<m;j+=(i*2))
            for (int k=0;k<i;k++)
            {
                //cerr<<gg<<" "<<b[gg][0][0]<<" "<<b[gg][0][1]<<" "<<b[gg][1][0]<<" "<<b[gg][1][1]<<endl;
                ll xx=a[j+k],yy=a[i+j+k];
                a[j+k]=b[gg][0][0]*xx+b[gg][0][1]*yy;
                a[i+j+k]=b[gg][1][0]*xx+b[gg][1][1]*yy;
            }
    }
    const int N=1e6;
    ll x[N],y[N];
    int main()
    {
       freopen("3.in","r",stdin);
       freopen("3.out","w",stdout);
       ios::sync_with_stdio(false);
       gao();
       cin>>n;
       ll ans=1;
       rep(i,0,n-1)
       {
            cin>>s[i];
            int now=0;
            dep(j,3,0)
              now=now*2+s[i][j]-'0';
            rep(i1,0,1)
           rep(j1,0,1) 
           {
             ah[i][i1][j1]=aa[now][i1][j1];
                bh[i][i1][j1]=bb[now][i1][j1];
                ch[i][i1][j1]=cc[now][i1][j1];
              }
            ans=ans*h[now];
       }
       m=1;
       rep(i,1,n) m=m*2;
       rep(i,0,m-1) cin>>x[i];
       rep(i,0,m-1) cin>>y[i];
       fwt(x,ah); fwt(y,bh);
       rep(i,0,m-1) x[i]=x[i]*y[i];
       fwt(x,ch);
       rep(i,0,m-1) x[i]=x[i]/ans;
       rep(i,0,m-1) cout<<x[i]<<" "; 
       return 0;
    }
    View Code

    https://zerol.me/2019/03/18/CF-102129A/

    https://codeforces.com/gym/102129

    这题是参考上面那个题解的

    egin{eqnarray}
    c_0 &=& (a_1+a_2)(b_1+b_2)
    c_0 + c_1 + c_2 &=& (a_0 + a_1 + a_2)(b_0 + b_1 + b_2)
    c_3 &=& a_2b_2
    c_1 + c_3 &=& (a_0 + a_2)(b_0 + b_2)
    end{eqnarray}

    按照如上化简之后就可以进行4进制下的fwt

    //#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
    
    //#include <immintrin.h>
    //#include <emmintrin.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define ll long long
    #define me(x) memset(x,0,sizeof(x))
    #define IL inline
    #define rint register int
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    struct re{
        int a,b,c;
    };
    int f(int x)
    {
        int k1=0,k2=1;
        while (x)
        {
            int t=x%3;
            x/=3;
            k1+=k2*t;
            k2=k2*4; 
        }
        return k1;
    }
    int m1,m2;
    const int N=(1<<24)+3;
    ll a[N];
    int b[N];
    void g1(ll &xa,ll &xb,ll &xc,ll &xd)
    {
        ll a=xa,b=xb,c=xc,d=xd;
        xa=b+c;
        xb=a+b+c; 
        xc=c;
        xd=a+c;
    }
    void g11(int &xa,int &xb,int &xc,int &xd)
    {
        int a=xa,b=xb,c=xc,d=xd;
        xa=b+c;
        xb=a+b+c; 
        xc=c;
        xd=a+c;
    }
    void g2(ll &xa,ll &xb,ll &xc,ll &xd)
    {
        ll a=xa,b=xb,c=xc,d=xd; 
        xa=a;
        xd=c;
        xb=d-xd;
        xc=b-xa-xb;
    }
    void fwt(int *a,int o)
    {
        for (int i=1;i<m2;i*=4)
          for (int j=0;j<m2;j+=(i*4))
            for (int k=0;k<i;k++)
            {
                if (o==0) g11(a[j+k],a[j+k+i],a[j+k+2*i],a[j+k+3*i]);
            }
    }
    void fwt(ll *a,int o)
    {
        for (int i=1;i<m2;i*=4)
          for (int j=0;j<m2;j+=(i*4))
            for (int k=0;k<i;k++)
            {
                if (o==0) g1(a[j+k],a[j+k+i],a[j+k+2*i],a[j+k+3*i]);
                else g2(a[j+k],a[j+k+i],a[j+k+2*i],a[j+k+3*i]);
            }
    }
    int main()
    {
       freopen("3.in","r",stdin);
       freopen("3.out","w",stdout);
       ios::sync_with_stdio(false);
       int n;
       cin>>n;
       m1=1,m2=1;
       rep(i,1,n) m1=m1*3,m2=m2*4;
       rep(i,0,m1-1) { cin>>a[f(i)];} 
       rep(i,0,m1-1) { cin>>b[f(i)];}
       fwt(a,0); fwt(b,0);
       rep(i,0,m2-1) a[i]=a[i]*b[i];
       fwt(a,1);
       rep(i,0,m1-1) cout<<a[f(i)]<<" ";
       return 0;
    }
    View Code

    还有k进制下的fwt

    https://www.cnblogs.com/reverymoon/p/10197711.html参考这个博客的

    这个矩阵是利用单位根

    因为要求$T1[x][i]*T2[x][j]=T3[x][k](i otimes j=k)$

    而${w_k}^{xi}*{w_k}^{xj}=w_k^{x(i+j)\%k}$

    所以只需要让$T[x][i]={w_k}^{xi}$

    egin{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}

    他的逆矩阵是

    $frac{1}{k}$ egin{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}

    这个代码有需要在写。。

  • 相关阅读:
    转:基于科大讯飞语音API语音识别开发详解
    转:Netty系列之Netty高性能之道
    转:hadoop知识整理
    转:nginx防DDOS攻击的简单配置
    转:Google论文之一----Bigtable学习翻译
    POJ 2112 Optimal Milking(最大流+二分)
    HDU 4647 Another Graph Game(贪心)
    HDU 4671 Partition(定理题)
    HDU 4648 Magic Pen 6
    HDU 4649 Professor Tian(DP)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/14981950.html
Copyright © 2020-2023  润新知