CodeForces 603 C.Lieges of Legendre(博弈论)

本文探讨了一种基于石子堆的游戏策略,通过分析不同数量石子堆的操作规则,利用数学归纳法确定了游戏的胜者。针对不同参数,讨论了奇数与偶数堆的不同策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

nn堆石子,第i堆有aiai个石子,每轮可以有两种操作,第一种是选一堆非空石子取走一个,第二种是对于一个有2x2x个石子的偶数堆,将其分成kkx个石子的堆,问谁必胜

Input

第一行两个整数n,kn,k,之后输入nn个整数ai(1n105,1k,ai109)

Output

输出胜者

Sample Input

2 1
3 4

Sample Output

Kevin

Solution

组合游戏,记sg[x]sg[x]xx个石子的堆的sg值,AA为若干非负整数的集合,mex(A)=min(NA)表示不是AA集合的自然数最小值

k为偶数,那么有2x2x个石子的偶数堆用第二种操作会变成偶数个xx个石子的堆,这种后继状态的sg值为偶数个sg[x]sg[x]异或,即为00,进而有sg[2x]=mex(0,sg[2x1]),暴力计算得sg[0,1,2,3,4]=0,1,2,0,1sg[0,1,2,3,4]=0,1,2,0,1,用数学归纳法验证,n2n≥2时,sg[2n1]=0,sg[2n]=1sg[2n−1]=0,sg[2n]=1

k=2k=2时显然成立结论成立,k=nk=n时若成立sg[2k1]=0,sg[2k]=1sg[2k−1]=0,sg[2k]=1,那么k=n+1k=n+1时:

sg[2k+1]=mex(sg[2k])=0sg[2k+1]=mex(sg[2k])=0sg[2k+2]=mex(0,sg[2k+1])=1sg[2k+2]=mex(0,sg[2k+1])=1

故结论成立,进而得到了任意nnsg

kk为奇数,那么有sg[2x]=mex(sg[2x1],sg[x]),暴力计算得sg[0,1,2,3,4,5]=0,1,0,1,2,0sg[0,1,2,3,4,5]=0,1,0,1,2,0,用数学归纳法验证,n2n≥2时,sg[2n]>0,sg[2n+1]=0sg[2n]>0,sg[2n+1]=0

k=2k=2时结论显然成立,k=nk=n时若成立sg[2k]>0,sg[2k+1]=0sg[2k]>0,sg[2k+1]=0,那么k=n+1k=n+1时:

sg[2k+2]=mex(sg[2k+1],sg[k+1])>0(sg[2k+1]=0)sg[2k+2]=mex(sg[2k+1],sg[k+1])>0(sg[2k+1]=0)sg[2k+3]=mex(sg[2k+2])=0sg[2k+3]=mex(sg[2k+2])=0

故结论成立,进而得到所有奇数的sgsg值,对于所有的sg[2x]sg[2x],递归求出sg[x]sg[x]即可,时间复杂度O(log2x)O(log2x)

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
#define maxn 111111
int n,k,a,f[5];
map<int,int>sg;
int solve(int a)
{
    if(a<5)return  f[a];
    if(a%2)return 0;
    return solve(a/2)==1?2:1;
}
int main()
{
    f[0]=0,f[1]=1,f[2]=0,f[3]=1,f[4]=2;
    scanf("%d%d",&n,&k);
    int ans=0;
    if(k%2==0)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            if(a==2)ans^=2;
            else if(a==1||a>2&&a%2==0)ans^=1;
        }
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a);
            ans^=solve(a);
        }
    }
    printf("%s\n",ans?"Kevin":"Nicky");
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值