正题
大意
有n堆石头,每堆石头有 个每次可以拿走一堆或者Y个(仅当 )。拿走最后一堆石头的人就赢了,两个人都是聪明绝顶的。
解题思路
考虑构建SG函数:
这样我们会发现如果x是质数,那么比他小的都在集合里,那么它的SG值就是之前最大的SG值+1,这样的话质数的SG值就是递增的。
我们再考虑合数,由于质数的SG值是递增的,我们会发现其实每个合数产生不了任何新的值,那么每个合数的SG值就是它的最小质因子的SG值。
这样的话质数的SG值就是它是第几个质数
我们用素数筛来计算。
代码
#include<cstdio>
using namespace std;
int t,n,ans,a,sg[1000001],tot;
void prime()
{
sg[1]=1;tot=1;//第一个特判
for (int i=2;i<=1000000;i++)
{
if (!sg[i])//没有被筛过
{
sg[i]=++tot;//统计第几个质数
for(int j=i;j<=1000000;j+=i)
if (!sg[j]) sg[j]=tot;//被最小的质因子筛掉
}
}
}
int main()
{
scanf("%d",&t);
prime();//预处理
while (t--)
{
scanf("%d",&n);
ans=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a);//输入
ans^=sg[a];//就SG函数的和
}
printf("%s\n",ans?"Alice":"Bob");//判断赢家
}
}