bzoj4589 Hard Nim(fwt_xor+快速幂,fwt入门题)

Posted live4m

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj4589 Hard Nim(fwt_xor+快速幂,fwt入门题)相关的知识,希望对你有一定的参考价值。

题意:

解法:

nim必胜的条件为石子数量异或和为0.

那么题意可以转化为:<=m的质数中,可重复的选出n个数,最后异或和为0的方案数.
n<=1e9,m<=5e4

令f[i][j]为选i个数,异或和为i的方案数
f[i][j]+=f[i-1][x]*f[1][y],其中x^y=j.
其实就是f[1][]异或卷积n次,
用fwt优化异或卷积的速度,用快速幂优化异或卷积的次数即可.

code:

#include<bits/stdc++.h>
#define int long long
#define PI pair<int,int>
using namespace std;
int ppow(int a,int b,int mod){
    int ans=1%mod;a%=mod;
    while(b){if(b&1)ans=1ll*ans*a%mod;a=1ll*a*a%mod;b>>=1;}
    return ans;
}
const int mod=1e9+7;
const int maxm=2e5+5;
const int inv2=ppow(2,mod-2,mod);
int p[maxm],c;
int np[maxm];
int a[maxm];
int ans[maxm];
int n,m;
int len;
void init(){
    for(int i=2;i<maxm;i++){
        if(!np[i]){
            p[c++]=i;
            for(int j=i+i;j<maxm;j+=i){
                np[j]=1;
            }
        }
    }
}
void fwt_xor(int *a, int op){
    for(int i=1;i<len;i<<=1){
        for(int j=0,p=i<<1;j<len;j+=p){
            for(int k=0;k<i;k++){
                int x=a[j+k],y=a[i+j+k];
                a[j+k]=(x+y)%mod;
                a[i+j+k]=(x-y+mod)%mod;
                if(op==-1){
                    a[j+k]=1ll*a[j+k]*inv2%mod;
                    a[i+j+k]=1ll*a[i+j+k]*inv2%mod;
                }
            }
        }
    }
}
void f_pow(int *a,int n){
    for(int i=0;i<len;i++)ans[i]=0;
    ans[0]=1;
    fwt_xor(a,1);
    fwt_xor(ans,1);
    while(n){
        if(n&1){
            for(int i=0;i<len;i++){
                ans[i]=1ll*ans[i]*a[i]%mod;
            }
        }
        for(int i=0;i<len;i++){
            a[i]=1ll*a[i]*a[i]%mod;
        }
        n>>=1;
    }
    fwt_xor(ans,-1);
}
void solve(){
    len=1;
    while(len<m*2)len<<=1;//因为异或会使得值域翻倍,所以这里取上限为m*2
    for(int i=0;i<len;i++)a[i]=0;
    for(int i=0;i<c;i++){
        if(p[i]>m)break;
        a[p[i]]=1;
    }
    f_pow(a,n);
    int res=ans[0];
    cout<<res<<endl;
}
signed main(){
    #ifndef ONLINE_JUDGE
    freopen("../in.txt","r",stdin);
    freopen("../out.txt","w",stdout);
    #endif
    ios::sync_with_stdio(0);cin.tie(0);
    init();
    while(cin>>n>>m){
        solve();
    }
    return 0;
}

以上是关于bzoj4589 Hard Nim(fwt_xor+快速幂,fwt入门题)的主要内容,如果未能解决你的问题,请参考以下文章

bzoj4589: Hard Nim fwt

bzoj4589 Hard Nim

bzoj 4589: Hard Nim

bzoj 4589 Hard Nim —— FWT

bzoj 4589 Hard Nim——FWT

BZOJ4589. Hard Nim