BZOJ4589: Hard Nim

来源:互联网 发布:python 双引号 变量 编辑:程序博客网 时间:2024/05/25 08:15

筛出不超过m的质数,然后可以DP
f[i][j]=f[i1][a]f[i1][b](a xor b=j)
然后可以快速幂
这时候就需要FWT了

学了一下FWT,Orz PoPoQQQ

因为不是FFT,不会有精度问题也没有指数问题,所以可以在快速幂前转FWT,快速幂算完后再DWT转回来

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long longusing namespace std;const int maxn = 70000;const ll Mod = 1e9+7;const ll N2 = Mod+1ll>>1;int p[maxn],pri;bool v[maxn];void pre(){    v[0]=v[1]=true;    for(int i=2;i<maxn;i++)    {        if(!v[i]) p[++pri]=i;        for(int j=1;j<=pri;j++)        {            int k=p[j]*i;            if(k>=maxn) break;            v[k]=true;            if(i%p[j]==0) break;        }    }}int n,N;ll st[maxn],ret[maxn];void FWT(ll f[],int m,int sig){    if(m==1) return;    int t=m>>1;    for(int i=0;i<t;i++)    {        (f[i]+=f[i+t])%=Mod;        f[i+t]=(f[i]-(f[i+t]<<1)+Mod)%Mod;        if(sig==-1) (f[i]*=N2)%=Mod,(f[i+t]*=N2)%=Mod;    }    FWT(f,t,sig); FWT(f+t,t,sig);}void pw(int k){    st,ret;    for(;k;k>>=1)    {        if(k&1) for(int j=0;j<N;j++) (ret[j]*=st[j])%=Mod;        for(int j=0;j<N;j++) (st[j]*=st[j])%=Mod;    }}int main(){    pre();    int k;    while(scanf("%d%d",&k,&n)!=EOF)    {        N=1; while(N<=n) N<<=1;        for(int i=0;i<N;i++) st[i]=0ll;        for(int i=0;i<=n;i++) st[i]=v[i]?0ll:1ll;        for(int i=0;i<maxn;i++) ret[i]=0ll;        ret[0]=1ll;        FWT(ret,N,1); FWT(st,N,1);        pw(k);        FWT(ret,N,-1);        if(ret[0]<0) ret[0]+=Mod;        printf("%lld\n",ret[0]);    }    return 0;}
0 0
原创粉丝点击