zoukankan      html  css  js  c++  java
  • ACdream 1112 Alice and Bob (博弈&&素数筛选优化)

    题目链接:传送门

    游戏规则:

    没次能够将一堆分成两堆 x = a*b (a!=1&&b!=1)x为原来堆的个数,a,b为新堆的个数。

    也能够将原来的堆的个数变成原来堆的约数y。y!=x。进行最后一次操作的人获胜。

    分析:

    也是一个去石头的游戏,因此我们仅仅须要将全部情况的sg值异或起来就好了。

    我们首先来考虑一堆。设这一堆的个数为x;

    那么全部的情况就是

    (a1,x/a1), (a2,x/a2),...,(an,x/an);或者(a1),(a2),..,(an)。

    由于数据量比較大,我们朴素的找约数肯定会超时。

    然后细致分析一下这个问题。由于我

    们都是环绕着约数来进行操作。那么也就相当于在对他的素因子的个数进行操作。

    x=a1^r1*a2^r2*...*an^rn;设sum = r1+r2+...+rn.

    然后全部的情况就能够表示为:

    (1,sum-1),(2,sum-2),...(sum/2,sum-sum/2)或者(1),(2),...(n-1)

    这样就大大减小了数据的范围。然后在计算sum的时候我们能够这样计算。

    设一个数为x,他的最小的素因子为y.则sum[x] = sum[x/y] + 1;

    代码例如以下:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    const int maxn = 5000010;
    
    int prime[maxn],cnt;
    bool isprime[maxn];
    int fac_num[maxn];
    int min_fac[maxn];
    
    int sg[100];
    
    void GetPirme(){
        cnt=0;
        memset(isprime,0,sizeof(isprime));
        memset(fac_num,-1,sizeof(fac_num));
        memset(min_fac,-1,sizeof(min_fac));
        for(int i=2;i<maxn;i++){
            if(!isprime[i]){
                prime[cnt++]=i;
                for(int j=i+i;j<maxn;j+=i){
                    isprime[j]=1;
                    if(min_fac[j]==-1)
                        min_fac[j]=i;
                }
                min_fac[i]=i;
            }
        }
    }
    
    int get_num(int x){
        if(x==1) return 0;
        if(fac_num[x]!=-1) return fac_num[x];
        return fac_num[x]=get_num(x/min_fac[x])+1;
    }
    
    int Get_Sg(int x){
        if(sg[x]!=-1) return sg[x];
        bool vis[100];
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=x;i++) vis[Get_Sg(x-i)]=1;
        for(int i=1;i<=x/2;i++)
            vis[Get_Sg(i)^Get_Sg(x-i)]=1;
        for(int i=0;;i++){
            if(!vis[i]){
                return sg[x]=i;
            }
        }
    }
    
    void init(){
        GetPirme();
        memset(sg,-1,sizeof(sg));
        sg[0]=0;
    }
    
    int main()
    {
        init();
        int n;
        while(~scanf("%d",&n)){
            int x ,ans=0;
            for(int i=0;i<n;i++){
                scanf("%d",&x);
                //cout<<"num: "<<get_num(x)<<endl;
                ans^=Get_Sg(get_num(x));
            }
            if(ans) puts("Alice");
            else puts("Bob");
        }
        return 0;
    }
    


     

  • 相关阅读:
    vue项目的骨架及常用组件介绍
    细谈最近上线的Vue2.0项目(一)
    【请求之密】payload和formData有什么不同?
    【19道XSS题目】不服来战!
    Hexo+Coding搭建免费博客之Hexo代码上传到Coding实现公网访问站点(三)
    Hexo+Coding搭建免费博客之Next主题设置(二)
    Hexo+Coding搭建免费博客之Hexo安装部署(一)
    Openstack-Queens详细安装教程
    ESXI安装报错,No Network adapters were detected...
    VMware ESXi 5.5组件安装过程记录
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5223405.html
Copyright © 2011-2022 走看看