BZOJ - 4589 Hard Nim (FWT)
FWT的板子题,思想不是很好理解,但代码还是非常好写的。
1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll mod=1e9+7,inv2=mod/2+1,N=2e5+10; 4 void fwt(ll* a,int n,int f) { 5 for(int d=1; d<n; d<<=1) 6 for(int i=0; i<n; i+=d<<1) 7 for(int j=0; j<d; ++j) { 8 ll x=a[i+j],y=a[i+j+d]; 9 a[i+j]=(x+y)%mod,a[i+j+d]=(x-y)%mod; 10 if(!~f)a[i+j]=a[i+j]*inv2%mod,a[i+j+d]=a[i+j+d]*inv2%mod; 11 } 12 } 13 ll Pow(ll x,ll p) {ll ret=1; for(; p; x=x*x%mod,p>>=1)if(p&1)ret=ret*x%mod; return ret;} 14 int n,m,pri[N]; 15 ll a[N]; 16 17 int main() { 18 for(int i=2; i<N; ++i)for(int j=2; i*j<N; ++j)pri[i*j]=1; 19 while(~scanf("%d%d",&n,&m)) { 20 int n2=1; 21 for(; n2<=m; n2<<=1); 22 for(int i=0; i<n2; ++i)a[i]=0; 23 for(int i=2; i<=m; ++i)if(!pri[i])a[i]=1; 24 fwt(a,n2,1); 25 for(int i=0; i<n2; ++i)a[i]=Pow(a[i],n); 26 fwt(a,n2,-1); 27 printf("%lld\n",(a[0]+mod)%mod); 28 } 29 return 0; 30 }