zoukankan      html  css  js  c++  java
  • 【BZOJ4589】Hard Nim(FWT)

    【BZOJ4589】Hard Nim(FWT)

    题面

    BZOJ

    Description

    Claris和NanoApe在玩石子游戏,他们有n堆石子,规则如下:

    1. Claris和NanoApe两个人轮流拿石子,Claris先拿。
    2. 每次只能从一堆中取若干个,可将一堆全取走,但不可不取,拿到最后1颗石子的人获胜。
      不同的初始局面,决定了最终的获胜者,有些局面下先拿的Claris会赢,其余的局面Claris会负。
      Claris很好奇,如果这n堆石子满足每堆石子的初始数量是不超过m的质数,而且他们都会按照最优策略玩游戏,那么NanoApe能获胜的局面有多少种。
      由于答案可能很大,你只需要给出答案对10^9+7取模的值。

    Input

    输入文件包含多组数据,以EOF为结尾。
    对于每组数据:
    共一行两个正整数n和m。
    每组数据有1<=n<=10^9, 2<=m<=50000。
    不超过80组数据。

    Sample Input

    3 7

    4 13

    Sample Output

    6

    120

    题解

    相当于变相的询问,对于给定的所有小于(m)的质数中
    选出(n)个数,他们的异或和为(0)的方案数
    如果(n)很小,我们可以一次次的做(FWT)
    但是(n<=10^9),所以用快速幂优化一下就行了
    中间没有必要做(IFWT)转换回去
    一直用(FWT)做最后再做一次(IFWT)就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MOD (1000000007)
    #define inv2 (500000004)
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    int a[1<<16],b[1<<16],N;
    void FWT(int *P,int opt)
    {
    	for(int i=2;i<=N;i<<=1)
    		for(int p=i>>1,j=0;j<N;j+=i)
    			for(int k=j;k<j+p;++k)
    			{
    				int x=P[k],y=P[k+p];
    				P[k]=(x+y)%MOD;P[k+p]=(x-y+MOD)%MOD;
    				if(opt==-1)P[k]=1ll*P[k]*inv2%MOD,P[k+p]=1ll*P[k+p]*inv2%MOD;
    			}
    }
    int n,m;
    bool zs[55555];
    void prime()
    {
    	zs[1]=true;
    	for(int i=2;i<=50000;++i)
    		if(!zs[i])
    			for(int j=i+i;j<=50000;j+=i)
    				zs[j]=true;
    }
    void fpow(int *a,int *b,int p)
    {
    	FWT(a,1);FWT(b,1);
    	while(p)
    	{
    		if(p&1)for(int i=0;i<N;++i)b[i]=1ll*b[i]*a[i]%MOD;
    		for(int i=0;i<N;++i)a[i]=1ll*a[i]*a[i]%MOD;
    		p>>=1;
    	}
    	FWT(b,-1);
    }
    int main()
    {
    	prime();
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		for(N=1;N<=m;N<<=1);
    		memset(a,0,sizeof(a));memset(b,0,sizeof(b));
    		for(int i=1;i<=m;++i)
    			if(!zs[i])a[i]=b[i]=1;
    		fpow(a,b,n-1);
    		printf("%d
    ",b[0]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Bootstrap
    继承与多态
    面对对象与封装
    antd表格排序
    样式文本过长用...显示的时候,用弹框来显示文本(react为例)
    锚点
    树形结构的搜索,只显示搜索内容
    fetch不携带cookie
    antd 给select下拉框添加懒加载
    post方法下载文件
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9065696.html
Copyright © 2011-2022 走看看