1 条题解

  • 0
    @ 2025-8-24 22:14:39

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar KesdiaelKen
    **

    搬运于2025-08-24 22:14:39,当前版本为作者最后更新于2019-12-19 15:48:15,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    本题为博弈论+数论题目,只需转化一下模型即可。

    生成函数只是个随机函数,按题意生成数据。其实是因为直接给数据文件太大无法上传

    下面分数据编号进行讲评。

    11

    m5m\le5,用boolbool数组f[i][j][k][s][t]f[i][j][k][s][t]表示某个状态下为必胜或必败(指的是面对当前局面人的胜负状态)。f[k][k][k][k][k]f[k][k][k][k][k]为末状态,必败。每个状态可以有若干个下接状态(进行一次设计后可以形成的不违规状态)。容易想到,如果所有下接状态均为必胜,则此状态必败;否则必胜。记忆化搜索即可。

    22

    kk减去每个初始示数,题意就可以理解为在任意一个位置上减11,不够减则借位。每个数从00kk。这不就是k+1k+1进制的减法吗?于是,题意转化为:给出nn个数,每次减去(k+1)i(k+1)^iii为任意自然数,不能减到小于00,轮流操作,问谁会面对全00的局面。则考虑每个数的胜负情况(记为f[i]f[i])。

    对于此点n=1n=1,只需考虑一个数的f[i]f[i]。由于22m,km,k范围较大,不能像11那样枚举下接状态。考虑f[i]f[i]是否具有规律。发现对于kk的奇偶不同,规律不同:下面分情况证明:

    对于kk为偶数,当2i2|if[i]=falsef[i]=false(败),否则为truetrue(胜)。证明:数学归纳法。当i=0,1i=0,1时成立。当i>1i>1,由于2k2|k2∤(k+1)i2\not|(k+1)^ii(k+1)ii-(k+1)^iii不同奇偶,则若ii为偶,所有i(k+1)ii-(k+1)^i为奇,f[i(k+1)i]=truef[i-(k+1)^i]=true,则f[i]=falsef[i]=falseii为奇同理。

    对于kk为奇数,当i>k+1i>k+1f[i]f[imod(k+2)]f[i]\equiv f[i\mod (k+2)];当ik+1i\le k+1f[i]=truef[i]=true(2∤i)or(i=k+1)(2\not|i )or(i=k+1)f[i]=falsef[i]=false(2i)and(ik+1)(2|i)and(i\not=k+1)。证明:数学归纳法。当i=0 to k+1i=0\space to\space k+1时易知成立。当i>k+1i>k+1时,(k+1)i=1 or 1(modk+2)(k+1)^i=1\space or\space -1(\mod k+2),则类似kk为偶数时进行归纳。

    kk为偶数的时候也可以转化为f[i]f[i]k+2k+2为循环的规律。

    规律得出,则可做。

    33

    存不下转换后的数。但考虑到最后的数要对k+2k+2取模,可以在读入的时候同时取模。因为是k+1k+1进制,对于奇数位,模k+2k+2的值为1-1乘此位上的数;对于偶数位,模k+2k+2的值为11乘上此位上的数。

    686-8

    有多个数,kk为偶数。先求出每个初始数的ff。由以上证明可看到kk为偶数时,赢状态的所有下接状态都为输状态,而输状态的所有下接状态都为赢状态。末状态所有数都为00,有偶数个赢状态。对于所有数,一次射击只能将一个数的ff变为相反的一个状态。因此对于一个人,他面对的所有数中赢状态总数一定。所以,若先手面对奇数个赢状态则必赢,偶数个则必输。

    55

    每个数都小于等于kk,即不可能取到kk为奇数的特殊状态ik+1(modk+2)i\equiv k+1(\mod k+2),等同于kk为偶数的状态,即赢状态只接输状态,输状态只接赢状态。做法同上。

    44

    只有两个数,可以进行特殊讨论解决。

    9179-17

    f[i]f[i]只保存赢或输不能为解决复杂的博弈信息提供足够有效信息。需要使用sgsg函数解决(不懂可看sg函数详解或自行查找资料)。令f[i]f[i]表示数iisgsg函数值。同上用数学归纳法可证明:kk为偶数时,将truetrue转为11falsefalse转为00即可;kk为奇数时,对于i≢k+1(modk+2)i\not\equiv k+1(\mod k+2),同上转换,否则f[i]=2f[i]=2。之后将每个数的sgsg函数值异或,异或值为00时必败,否则必胜。

    事实上这个结论不用sgsg函数也可以推的出来。

    标程:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<string>
    using namespace std;
    unsigned long long k,a,b,c,sg,x,lc;
    inline unsigned long long generate(unsigned long long&a,unsigned long long&b,unsigned long long&c,unsigned long long&k)
    { 
    	a<<=19;a+=b+c;
    	a<<=26;a^=c+=a+81;b--;
    	a<<=7;a>>=(b^c^1145)&14;
    	c*=a;a|=b+=c;a^=b&c;
    	return a%(k+1);
    }
    int main()
    {
    	int n,m,t;scanf("%d",&t);
    	while(t--)
    	{
    		scanf("%lld%d%d%lld%lld%lld",&k,&n,&m,&a,&b,&c);
    		x=0;
    		for(int i=1;i<=n;i++,x^=sg)
    		{
    			sg=0;
    			for(int j=1;j<=m;j++)
    			{
    				lc=generate(a,b,c,k);
    				sg=(sg+((j&1)?(k-lc):(lc+2)))%(k+2);
    			}
    			if((k&1)&&sg==k+1)sg=2;
    			else sg&=1;
    		}
    		if(x)printf("YES\n");else printf("NO\n");
    	}
    	return 0;
    }
    
    • 1

    信息

    ID
    4568
    时间
    1000ms
    内存
    125MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者