zoukankan      html  css  js  c++  java
  • [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
  • 相关阅读:
    vue element 表格错位问题
    echarts tooltip 按值的降序显示 tip 信息
    前端 玫瑰花小样式
    echarts X轴数据过多批量显示
    微信js sdk的使用初步理解
    对象 的循环嵌套
    移动端拉起电话请求
    js后加版本号
    数组排序于数组去重
    es6数组的方法
  • 原文地址:https://www.cnblogs.com/oldmanren/p/3607987.html
Copyright © 2011-2022 走看看