bzoj 4589 FWT

时间:2022-09-08 21:32:48
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e4+;
const int mod=1e9+;
const int MOD=1e9+;
const int inv2=5e8+;
int a[<<],b[<<],N;
int n,m;
bool vis[maxn];
int prime[maxn];
int tot=;
void get_prime() // prime=0;else 1;
{
vis[]=;
for(int i=;i<maxn;i++)
{
if(!vis[i]) prime[tot++]=i;
for(int j=;j<tot && i*prime[j]<maxn;j++)
{
vis[i*prime[j]]=;
if(i%prime[j]==) break;
}
} //for(int i=0;i<=40;i++) cout<<prime[i]<<endl;
}
void FWT(int *P,int opt)
{
for(int i=;i<=N;i<<=)
for(int p=i>>,j=;j<N;j+=i)
for(int k=j;k<j+p;++k)
{
int x=P[k],y=P[k+p];
P[k]=(x+y)%MOD;P[k+p]=(x-y+MOD)%MOD;
if(opt==-)P[k]=1ll*P[k]*inv2%MOD,P[k+p]=1ll*P[k+p]*inv2%MOD;
}
}
void fpow(int *a,int *b,int p)
{
FWT(a,);
FWT(b,);
while(p)
{
if(p&)for(int i=;i<N;++i)b[i]=1ll*b[i]*a[i]%MOD;
for(int i=;i<N;++i)a[i]=1ll*a[i]*a[i]%MOD;
p>>=;
}
FWT(b,-);
}
int main()
{
get_prime();
while(scanf("%d %d",&n,&m)!=EOF)
{
N=; while(N<=m) N=N<<;
memset(a,,sizeof(a));
memset(b,,sizeof(b));
for(int i=;i<=m;i++) if(!vis[i]) a[i]=b[i]=;
fpow(a,b,n-);
printf("%d\n",b[]);
}
return ;
}