1. 程式人生 > >BZOJ4589:Hard Nim——題解

BZOJ4589:Hard Nim——題解

博客 AS 快速 是把 其余 line ati sum tar

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

Claris和NanoApe在玩石子遊戲,他們有n堆石子,規則如下: 1. Claris和NanoApe兩個人輪流拿石子,Claris先拿。 2. 每次只能從一堆中取若幹個,可將一堆全取走,但不可不取,拿到最後1顆石子的人獲勝。 不同的初始局面,決定了最終的獲勝者,有些局面下先拿的Claris會贏,其余的局面Claris會負。 Claris很好奇,如果這n堆石子滿足每堆石子的初始數量是不超過m的質數,而且他們都會按照最優策略玩遊戲,那麽NanoApe能獲勝的局面有多少種。 由於答案可能很大,你只需要給出答案對10^9+7取模的值。

天哪這個tinymce可以用latex我才知道……以及我還是想不到dp啊。

用到一個結論:後手獲勝條件是每堆石子異或和為0。

設$f[i][j]$為前$i$堆異或和為$j$的方案數,$g[i]$表示$i$是否為質數。

於是$f[i][j]=\sum_{k=0}^mf[i-1][j\oplus k]g[k]$

然後變成卷積就是$f[i][j]=\sum_{a\oplus b=j}f[i-1][a]g[b]$

同樣還是把$f[i-1][a]$遞歸展開發現是卷積套卷積……n次,於是FWT快速冪就好了。

#include<map>
#include
<cmath> #include<stack> #include<queue> #include<cstdio> #include<cctype> #include<vector> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; const int N=1e5+5;
const int p=1e9+7; const int inv=500000004; inline int add(int x,int y){ x+=y;if(x>=p)x-=p;return x; } inline int sub(int x,int y){ x-=y;if(x<0)x+=p;return x; } void FWT(int a[],int n,int on){ for(int i=1;i<n;i<<=1){ for(int j=0;j<n;j+=(i<<1)){ for(int k=0;k<i;k++){ int u=a[j+k],t=a[j+k+i]; a[j+k]=add(u,t); a[j+k+i]=sub(u,t); if(on==-1){ a[j+k]=(ll)a[j+k]*inv%p; a[j+k+i]=(ll)a[j+k+i]*inv%p; } } } } } int qpow(int k,int n){ int res=1; while(n){ if(n&1)res=(ll)res*k%p; k=(ll)k*k%p;n>>=1; } return res; } int pri[N],g[N],a[N],b[N],tot; void Euler(int n){ g[0]=g[1]=1; for(int i=2;i<=n;i++){ if(!g[i])pri[++tot]=i; for(int j=1;j<=tot;j++){ if(i*pri[j]>n)break; g[i*pri[j]]=1; if(i%pri[j]==0)break; } } for(int i=0;i<=n;i++)g[i]^=1; } int n,m; int main(){ Euler(5e4); while(scanf("%d%d",&n,&m)!=EOF){ int len=1; while(len<=m)len<<=1; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); a[0]=1; for(int i=0;i<=m;i++)b[i]=g[i]; FWT(a,len,1);FWT(b,len,1); for(int i=0;i<len;i++)a[i]=(ll)a[i]*qpow(b[i],n)%p; FWT(a,len,-1); printf("%d\n",a[0]); } return 0; }

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+歡迎訪問我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4589:Hard Nim——題解