[BZOJ4589]Hard Nim
阿新 • • 發佈:2018-10-02
rand xor str online clas signed bzoj esp name
description
BZOJ
題意:\(n\)堆式子,每堆石子數量為\(\le m\)的質數,對於每一個局面玩\(Nim\)遊戲,求後手必勝的方案數。
data range
\[n\le 10^9,m\le 5\times 10^4\]
solution
直接\(FWT\)多項式快速冪即可。
之前寫的多項式快速冪一直是\(O(mlogmlogn)\)
然後在這一道題上\(T\)了...
\(\%\)了一發\(yyb\)的代碼才知道原來可以快速冪的時候可以不用每次\(FWT\)
這樣就變成\(O(m(logm+logn))\)的了
orz 神仙yyb
Code
#include<algorithm> #include<iostream> #include<cstdlib> #include<iomanip> #include<cstring> #include<complex> #include<vector> #include<cstdio> #include<string> #include<bitset> #include<ctime> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define Cpy(x,y) memcpy(x,y,sizeof(x)) #define Set(x,y) memset(x,y,sizeof(x)) #define FILE "a" #define mp make_pair #define pb push_back #define RG register #define il inline using namespace std; typedef unsigned long long ull; typedef vector<int>VI; typedef long long ll; typedef double dd; const int N=1<<16; const int M=1e5+10; const int mod=1e9+7; const int base=26; const dd eps=1e-6; const int inf=2147483647; const ll INF=1ll<<60; const ll P=100000; il ll read(){ RG ll data=0,w=1;RG char ch=getchar(); while(ch!=‘-‘&&(ch<‘0‘||ch>‘9‘))ch=getchar(); if(ch==‘-‘)w=-1,ch=getchar(); while(ch<=‘9‘&&ch>=‘0‘)data=data*10+ch-48,ch=getchar(); return data*w; } il void file(){ srand(time(NULL)+rand()); freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); } int pri[N];bool vis[N]; il void upd(int &a,int b){a+=b;if(a>=mod)a-=mod;} il void dec(int &a,int b){if(b)upd(a,mod-b);} il void sieve(){ vis[1]=1; for(RG int i=2;i<N;i++){ if(!vis[i])pri[++pri[0]]=i; for(RG int j=1;j<=pri[0]&&1ll*i*pri[j]<N;j++){ vis[i*pri[j]]=1;if(i%pri[j]==0)break; } } } il void FWT_xor(int *a,int n,int opt){ for(RG int i=1,x,y,inv2=(mod+1)/2;i<n;i<<=1) for(RG int j=0,p=i<<1;j<n;j+=p) for(RG int k=0;k<i;k++){ x=a[j+k];y=a[i+j+k];a[i+j+k]=x; upd(a[j+k],y);dec(a[i+j+k],y); if(opt==-1)a[j+k]=1ll*a[j+k]*inv2%mod,a[i+j+k]=1ll*a[i+j+k]*inv2%mod; } } int f[N],g[N]; int main() { sieve();RG int n,m; while(scanf("%d%d",&n,&m)!=EOF){ memset(f,0,sizeof(f));memset(g,0,sizeof(g));f[0]=1; for(RG int i=1;pri[i]<=m&&i<=pri[0];i++)g[pri[i]]=1; FWT_xor(f,N,1);FWT_xor(g,N,1); while(n){ if(n&1)for(RG int i=0;i<N;i++)f[i]=1ll*f[i]*g[i]%mod; for(RG int i=0;i<N;i++)g[i]=1ll*g[i]*g[i]%mod; n>>=1; } FWT_xor(f,N,-1); printf("%d\n",f[0]); } return 0; }
[BZOJ4589]Hard Nim