zoukankan      html  css  js  c++  java
  • LOJ#152. 子集卷积

    终于 get 到了子集卷积的正确姿势,以前竟然都是用异或卷积写的.  

    众所周知,异或卷积由于涉及到乘法所以会比较慢,那我们用或卷积就好了!   

    code: 

    #include <bits/stdc++.h>     
    #define N (1<<21)  
    #define ll long long 
    #define mod 1000000009    
    #define lowbit(x) ((x)&(-(x)))
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;     
    int n,inv2,lim;      
    int f[N],g[N],A[21][N],B[21][N],C[21][N],cnt[N]; 
    int qpow(int x,int y) 
    {
        int tmp=1;  
        for(;y;y>>=1,x=(ll)x*x%mod) if(y&1) tmp=(ll)tmp*x%mod;  
        return tmp; 
    }  
    int INV(int x) { return qpow(x,mod-2); }  
    void FWT(int *a) 
    {   
        for(int len=1;len<lim;len<<=1) 
            for(int i=0;i<lim;i+=len<<1) 
                for(int j=0;j<len;++j) 
                    (a[i+j+len]+=a[i+j])%=mod;      
    }
    void IFWT(int *a) 
    {      
        for(int len=1;len<lim;len<<=1) 
            for(int i=0;i<lim;i+=len<<1) 
                for(int j=0;j<len;++j)  
                    (a[i+j+len]+=mod-a[i+j])%=mod;  
    
    }    
    char *p1,*p2,buf[100000];  
    #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)  
    int rd() 
    {
        int x=0; char c=nc(); 
        while(c<48) c=nc();  
        while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc();   
        return x;  
    }   
    void print(int x) { if(x>=10) print(x/10); putchar(x%10+'0');}
    int main() 
    { 
        // setIO("input");                 
        n=rd(),lim=1<<n;     
        for(int i=0;i<lim;++i) f[i]=rd(); 
        for(int i=0;i<lim;++i) g[i]=rd();      
        for(int i=1;i<lim;++i) cnt[i]=cnt[i-lowbit(i)]+1;  
        for(int i=0;i<lim;++i) A[cnt[i]][i]=f[i],B[cnt[i]][i]=g[i];          
        for(int i=0;i<=n;++i)  FWT(A[i]),FWT(B[i]);   
        for(int i=0;i<=n;++i)    
        {
            for(int j=0;j<=n;++j)   
                if(i+j<=n) 
                {    
                    for(int k=0;k<lim;++k) (C[i+j][k]+=(ll)A[i][k]*B[j][k]%mod)%=mod;  
                }    
        }          
        for(int i=0;i<=n;++i)  IFWT(C[i]);          
        for(int i=0;i<lim;++i) print(C[cnt[i]][i]),putchar(' ');      
        return 0; 
    }
    

      

  • 相关阅读:
    JBoss无规律自动关闭故障定位
    使用Js脚本 修改控制IE的注册表相关设置(activex等)
    EJB到底是什么,真的那么神秘吗??
    MyEclipse 8.5 优化实例
    ORACLE修改用户表所属表空间的步骤
    Ora-01536:超出了表空间users的空间限量(转)
    Houdini Python开发实战 课程笔记
    Houdini Mac 添加external editor
    Xcode 导出C++项目在其他电脑执行
    Xcode中opengl的配置
  • 原文地址:https://www.cnblogs.com/guangheli/p/13082762.html
Copyright © 2011-2022 走看看