题意:有N个数,Alice 和 Bob 轮流对这些数进行操作,若一个数 n=a*b且a>1,b>1,可以将该数变成 a 和 b 两个数;

或者可以减少为a或b,Alice先,问谁能赢

思路:首先单看对每个数进行除法的操作,我们可以知道其实是在除以每个数的素因子或素因子之间的积

比如 70=2*5*7 我们可以变成 10(2*5)或 14(2*7) 或 35(5*7)或 2 或 5 或 7 或 1 这七种状态

当我们把他们(2,5,7)当作3个石子也就是一堆时,然而实际上我们是将这堆石子进行nim游戏

我拿走一个石子 =》 10(2*5) 我拿走了石子7

14 (2*7) 我拿走了石子5

35 (5*7) 我拿走了石子2

我拿走两个石子 =》 2    我拿走了石子5 和 石子7

5    我拿走了石子2 和 石子7

7    我拿走了石子2 和 石子5

我拿走三个石子 =》 1     我拿走了石子2 和 石子5 和 石子7

接下来我们分析把一个数n=a*b变成 a 和 b ,其实这里上面的思想很像,把它当作石子的分堆

我可以分成             第一种 10(2*5) 和 7

第二种 14(2*7) 和 5

第三种 35(5*7) 和 2

综上所诉,根据正整数唯一分解定理,任何一个正整数x必然有x=(p1^r1)*(p2^r2)*......*(pn^rn)

定义sum=r1+r2+...+rn,这个sum的值就是这堆石子的总数,那么sg=sg[sum1]^sg[susm2]^....

问题又来了? 这个sum我们应该如何求呢?

我们可以通过素数筛得到每一个数的最小质因子,我们得到一个类似于递推的公式

一个正整数的质因子的个数=(这个正整数 / 这个数的最小质因子 所得数) 的质因子个数 + 1(也就是加上这是最小质因子的数量 1)

接下来代码实现就可以了

代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 5000000
using namespace std; int prime[maxn+],k=,samll[maxn],sum[maxn];
bool visit[maxn+];
int sg[]; void get_prime()
{
memset(visit,false,sizeof(visit));
memset(samll,,sizeof(samll));
memset(sum,,sizeof(sum));
for(int i=;i<=maxn;i++)
{
if(visit[i]==false)
{
prime[k++]=i;
for(int j=i+i;j<=maxn;j+=i)
{
visit[j]=true;
if(samll[j]==) samll[j]=i;
}
samll[i]=i;
}
}
for(int i=;i<=maxn;i++)
sum[i]=sum[i/samll[i]]+;
} int get(int n)
{
if(sg[n]!=-) return sg[n];
bool vis[];
memset(vis,false,sizeof(vis));
for(int i=;i<=n;i++)
vis[get(n-i)]=true;
for(int i=;i<=n/;i++)
vis[get(i)^get(n-i)]=true;
int k;
for(int i=;i<;i++)
{
if(vis[i]==false)
{
return sg[n]=i;
}
}
} int main()
{
get_prime();
memset(sg,-,sizeof(sg));
sg[]=;
sg[]=;
for(int i=;i<=;i++)
{
get(i);
}
int n;
while(cin>>n)
{
int ans=;
for(int i=;i<=n;i++)
{
int x;
scanf("%d",&x);
ans=ans^sg[sum[x]];
}
if(ans)
cout<<"Alice"<<endl;
else
cout<<"Bob"<<endl;
}
return ;
}

ACdream 1112 Alice and Bob (sg函数的变形+素数筛)的更多相关文章

  1. ACdream 1112 Alice and Bob(素筛+博弈SG函数)

    Alice and Bob Time Limit:3000MS     Memory Limit:128000KB     64bit IO Format:%lld & %llu Submit ...

  2. 2014 Super Training #6 A Alice and Bob --SG函数

    原题: ZOJ 3666 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3666 博弈问题. 题意:给你1~N个位置,N是最 ...

  3. ACdream 1112 Alice and Bob (博弈&amp;&amp;素数筛选优化)

    题目链接:传送门 游戏规则: 没次能够将一堆分成两堆 x = a*b (a!=1&&b!=1)x为原来堆的个数,a,b为新堆的个数. 也能够将原来的堆的个数变成原来堆的约数y.y!=x ...

  4. sg函数的变形 - 可以将一堆石子分开

    Nim is a two-player mathematic game of strategy in which players take turns removing objects from di ...

  5. hdu 3032 Nim or not Nim? sg函数 难度:0

    Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  6. ACdream群赛1112(Alice and Bob)

    题意:http://acdream.info/problem?pid=1112 Problem Description Here  is Alice and Bob again ! Alice and ...

  7. uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数)

    uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数) uoj 题解时间 考虑如何求出每棵树(子树)的 $ SG $ . 众所周知一个状态的 $ SG $ 是其后继的 $ mex $ ...

  8. ZOJ 3529 A Game Between Alice and Bob(博弈论-sg函数)

    ZOJ 3529 - A Game Between Alice and Bob Time Limit:5000MS     Memory Limit:262144KB     64bit IO For ...

  9. Alice and Bob HDU - 4111 (SG函数)

    Alice and Bob are very smart guys and they like to play all kinds of games in their spare time. The ...

随机推荐

  1. [Usaco2014 Open Gold ]Cow Optics (树状数组+扫描线/函数式线段树)

    这道题一上手就知道怎么做了= = 直接求出原光路和从目标点出发的光路,求这些光路的交点就行了 然后用树状数组+扫描线或函数式线段树就能过了= = 大量的离散+模拟+二分什么的特别恶心,考试的时候是想到 ...

  2. 支持缩放的fresco图片控件 —— fresco sample: ZoomableDraweeView

    最近在实现一个类似淘宝中的评论列表的功能,其中要在列表中显示评论图,点击图片后显示大图进行查看,各家app几乎都会有这样的功能. 可以看到,一个体验较好的查看大图的基本功能有, 第一,左右滑动时切换图 ...

  3. p1154 地平线

    题目描述 Farmer John的牛们认为,太阳升起的那一刻是一天中最美好的,在那时她们可以看到远方城市模糊的轮廓.显然,这些轮廓其实是城市里建筑物模糊的影子. 建筑物的影子实在太模糊了,牛们只好把它 ...

  4. Activiti工作流(一)之基本操作介绍

    工作流的概念: 工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息或 ...

  5. 模拟做饭系统(java+线程中的join方法)

    (一)项目框架分析 妈妈要去做饭,发现没有酱油,让儿子去买酱油,然后回来做饭. 根据面向对象的思想,有两个对象,妈妈和儿子 主要有两个方法: (一)没有线程控制(即儿子没有买酱油回来妈妈就做好饭了)+ ...

  6. c风格字符串,字符串字面值,c++字符串

    C风格字符串:本质上就是以空字符null为结束符的数组 可以简单的理解为:有'\0'的是c风格字符串,无'\0'的是普通字符数组 字符串字面值:是一串常量字符,字符串字面值常量用双引号括起来的零个或多 ...

  7. Java字节码操纵框架ASM小试

    本文主要内容: ASM是什么 JVM指令 Java字节码文件 ASM编程模型 ASM示例 参考资料汇总 JVM详细指令 ASM是什么 ASM是一个Java字节码操纵框架,它能被用来动态生成类或者增强既 ...

  8. UI状态控制

    if(BillBaseStatusEnum.ADD==this.editData.getBaseStatus()){ this.btnSave.setEnabled(true); this.btnSu ...

  9. 从零开始学习Vue(三)

    我们从一个例子来学习组件,vuejs2.0实战:仿豆瓣app项目,创建自定义组件tabbar 这个例子用到其他组件,对于初学者来说,一下子要了解那么多组件的使用,会变得一头雾水.所以我把这个例子改写了 ...

  10. NodeJs开发的CLI——与telnet进行通信的聊天程序

    前言: (在NodeJs中,我们想要开启一个tcp协议的做法就是引入net内置对象:      const net = require('net'); ——ES6      var net = req ...