zoukankan      html  css  js  c++  java
  • bzoj千题计划308:bzoj4589: Hard Nim(倍增FWT+生成函数)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4589

    n*m*m 做法

    dp[i][j] 前i堆石子,异或和为j的方案数

     第一重循环可以矩阵快速幂优化

    后面求出序列的生成函数可以FWT优化

    做log次FWT也很慢(logn*m*logm)

    两个合并就是倍增FWT,即先对生成函数的序列做一次正变换,对正变换得到的每个结果快速幂,最后逆变换回去

    时间复杂度O(logn*m+m*logm)

    生成函数:是质数则系数为1,否则为0

    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    #define N 50001
    
    const int mod=1e9+7;
    
    const int M=1<<16;
    
    int inv;
    
    int a[N];
    
    int b[M+1];
    
    void FWT(int *a,int n)
    {
        int x,y;
        for(int d=1;d<n;d<<=1)
            for(int m=d<<1,i=0;i<n;i+=m)
                for(int j=0;j<d;++j)
                {
                    x=a[i+j]; y=a[i+j+d];
                    a[i+j]=x+y; a[i+j+d]=x-y;
                    a[i+j]-=a[i+j]>=mod ? mod : 0;
                    a[i+j+d]+=a[i+j+d]<0 ? mod : 0;
                }
    }
    
    void IFWT(int *a,int n)
    {
        int x,y;
        for(int d=1;d<n;d<<=1)
            for(int m=d<<1,i=0;i<n;i+=m)
                for(int j=0;j<d;++j)
                {
                    x=a[i+j]; y=a[i+j+d];
                    a[i+j]=1LL*(x+y)*inv%mod;
                    a[i+j+d]=1LL*(x-y+mod)%mod*inv%mod;
                }
    }
    
    int Pow(int a,int b)
    {
        int res=1;
        for(;b;a=1LL*a*a%mod,b>>=1)
            if(b&1) res=1LL*res*a%mod;
        return res;
    }
    
    int main()
    {
        for(int i=2;i<N;++i) a[i]=1;
        for(int i=2;i<N;++i)
            if(a[i])
                for(int j=2;i*j<N;++j) 
                    a[i*j]=0;
        inv=Pow(2,mod-2);
        int n,m;
        int len;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            memset(b,0,sizeof(b));
            for(int i=1;i<=m;++i) b[i]=a[i];
            len=1;
            while(len<=m) len<<=1;
            FWT(b,len);
            for(int i=0;i<len;++i) b[i]=Pow(b[i],n);
            IFWT(b,len);
            printf("%d
    ",b[0]);
        }
    }
  • 相关阅读:
    XML 浏览器支持
    浏览器中的XML
    C/C++中判断某一文件或目录是否存在
    C/C++程序员必须熟练应用的开源项目 -- 转
    VC 中窗口的销毁
    sql proc触发异常处理回滚
    为Array 添加indexOf
    Js的两种post方式
    sql 针对多个id或名称的分割和组合
    sql 查看语句的性能
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8953849.html
Copyright © 2011-2022 走看看