[TCSRM518Div1]Nim

共K堆石子,数量均为<=L的质数,问初始必败状态的数量。

暴力dp就是f(i,x^y)+=f(i-1,x) y为质数

转换成分治f(i,x^y)=f(i/2,x)*f(i/2,y)(i为奇数乘个f(1))

暴力做是L^2

然后分治乘法可以搞。

一般分治乘法为(Ax+B)(Cx+D)=ACxx+BD+[(A+B)(C-D)-AC-BD]x  T(N)=3*F(N/2)+O(N)

由于是xor,令x=2^k  则式子变为(Ax+B)(Cx+D)=(AD+BC)x+(AC+BD)=(P-Q)/2*x+(P+Q)/2 令P=(A+B)(C+D),Q=(A-B)*(C-D)  T(N)=2F(N/2)+O(N)=O(NlogN)

const int L=1<<16;
const int mod=int(1e9)+7;
const int inv2=500000004;
bool pd[50010];
int n,D,F[L];
int res[L],ans[L];
int a[20][L],b[20][L],t0[20][L],t1[20][L];
void mul(int d)
{
    if(d==0){a[0][0]=1LL*a[0][0]*b[0][0]%mod;return;}
    int i,w=1<<(d-1);
    rep(i,0,w-1)a[d-1][i]=(a[d][i]+a[d][i+w])%mod,b[d-1][i]=(b[d][i]+b[d][i+w])%mod;    mul(d-1);
    CP(t0[d],a[d-1],w);
    rep(i,0,w-1)a[d-1][i]=(a[d][i]-a[d][i+w])%mod,b[d-1][i]=(b[d][i]-b[d][i+w])%mod;    mul(d-1);
    CP(t1[d],a[d-1],w);
    rep(i,0,w-1)a[d][i]=1LL*(t0[d][i]+t1[d][i])*inv2%mod,a[d][i+w]=1LL*(t0[d][i]-t1[d][i])*inv2%mod;
}
void MUL(int*x,int*y)
{
    CP(a[D],x,n);
    CP(b[D],y,n);
    mul(D);
    CP(x,a[D],n);
}
class Nim
{
    public:
        int count(int K,int L)
        {
            int i,j;
            rep(i,2,L)if(!pd[i])rep(j,2,L/i)pd[i*j]=1;                
            rep(i,2,L)if(!pd[i])F[i]=1;
            for(n=1,D=0;n<=L;n*=2,D++);
            ans[0]=1;for(;K;K>>=1,MUL(F,F))if(K&1)MUL(ans,F);
            return (ans[0]%mod+mod)%mod;
        }    
}TC;
View Code

 

 

posted @ 2014-03-18 16:04  FancyCoder0  阅读(1031)  评论(0编辑  收藏  举报