zoukankan      html  css  js  c++  java
  • FWT(快速沃尔什变换)

    作用

     A,B,C均为多项式。在nlogn的时间复杂度内求C=A&B,C=A|B,C=A^B;

    过程

      设A经过快速沃尔什变换后为FWT(A),FWT(C)[i]=FWT(A)[i]*FWT(B)[i];再通过FWT(C)推出C;

    模板:https://www.luogu.org/problemnew/show/P4717

    #include<cstdio>
    #include<iostream>
    #include<ctype.h>
    using namespace std;
    #define ll long long
    inline ll rd()
    {
        ll x=0,f=1;char c=getchar();
        while(!isdigit(c)){if(c=='-')f=-f;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return x*f;
    }
    const int N=(1<<17)+13,P=998244353;
    int ad(int x,int y){return x+y<P?x+y:x+y-P;}
    void fwto(int *a,int n)
    {
        for(int i=2,l=1;i<=n;i<<=1,l<<=1)
            for(int j=1;j<=n;j+=i)
                for(int k=0;k<l;k++)
                a[j+k+l]=ad(a[j+k+l],a[j+k]);
    }
    void ifwto(int *a,int n)
    {
        for(int i=2,l=1;i<=n;i<<=1,l<<=1)
            for(int j=1;j<=n;j+=i)
                for(int k=0;k<l;k++)
                a[j+k+l]=ad(a[j+k+l],P-a[j+k]);
    }
    void fwta(int *a,int n)
    {
        for(int i=2,l=1;i<=n;i<<=1,l<<=1)
            for(int j=1;j<=n;j+=i)
                for(int k=0;k<l;k++)
                a[j+k]=ad(a[j+k+l],a[j+k]);
    }
    void ifwta(int *a,int n)
    {
        for(int i=2,l=1;i<=n;i<<=1,l<<=1)
            for(int j=1;j<=n;j+=i)
                for(int k=0;k<l;k++)
                a[j+k]=ad(P-a[j+k+l],a[j+k]);
    }
    int ch2(int x){return x&1?(x+P)>>1:x>>1;}
    int ch(ll x,ll y){return x*y<P?x*y:x*y%P;}
    void fwtx(int *a,int n)
    {
        for(int i=2,l=1;i<=n;i<<=1,l<<=1)
            for(int j=1;j<=n;j+=i)
                for(int k=0,t;k<l;k++)
                    t=a[j+k+l],a[j+k+l]=ad(P-t,a[j+k]),a[j+k]=ad(t,a[j+k]);
    }
    void ifwtx(int *a,int n)
    {
        for(int i=2,l=1;i<=n;i<<=1,l<<=1)
            for(int j=1;j<=n;j+=i)
                for(int k=0,t;k<l;k++)
                    t=a[j+k+l],a[j+k+l]=ch2(ad(P-t,a[j+k])),a[j+k]=ch2(ad(t,a[j+k]));
    }
    int a[N],b[N],c[N];
    int main()
    {
        int n=rd();n=1<<n;
        for(int i=1;i<=n;i++) a[i]=rd();
        for(int j=1;j<=n;j++) b[j]=rd();
        fwto(a,n);fwto(b,n);for(int i=1;i<=n;i++) c[i]=ch(a[i],b[i]);
        ifwto(a,n);ifwto(b,n);ifwto(c,n);for(int i=1;i<=n;i++) printf("%d ",c[i]);printf("
    ");
        fwta(a,n);fwta(b,n);for(int i=1;i<=n;i++) c[i]=ch(a[i],b[i]);
        ifwta(a,n);ifwta(b,n);ifwta(c,n);for(int i=1;i<=n;i++) printf("%d ",c[i]);printf("
    ");
        fwtx(a,n);fwtx(b,n);for(int i=1;i<=n;i++) c[i]=ch(a[i],b[i]);
        ifwtx(c,n);for(int i=1;i<=n;i++) printf("%d ",c[i]); 
    }

      

  • 相关阅读:
    两指针--减少数组循环
    python与正则表达式
    python 获取网页图片
    python学习 第一天
    jquery中的基本理解以及样式属性操作
    webapi中的三大家族
    BOM中的其他对象以及短路运算
    BOM中的api
    事件冒泡和事件捕获
    webapi中注册事件以及解绑事件
  • 原文地址:https://www.cnblogs.com/LWL--Figthing/p/10959602.html
Copyright © 2011-2022 走看看