zoukankan      html  css  js  c++  java
  • 【欧几里德的游戏】

    这道题好神仙啊

    我们推一下(SG)函数

    显然答案就是(SG(n,m))(SG(n,m)=0)则先手败,否则先手胜

    首先几个非常明显的地方(SG(n,0)=0),这是显然的,上来就面对了必败状态

    之后看看(SG)是如何转移的

    [SG(n,m)=mex{SG(n-m,m,SG(n-2*m,m)...SG(m,n\%m))} ]

    (mex)是基于集合的操作,(mex(S)={min(x)in N|x otin S}),也就是不属于集合(S)的最小自然数

    非常显然的是

    [SG(n-m,m)=mex{SG(n-2*m,m),SG(n-3*m,m)...SG(m,n\%m)} ]

    之后会惊奇的发现好像我们知道了(SG(m,n\%m))就可以推所有了

    分类讨论一波

    如果(SG(m,n\%m)=1),那么由于(SG(m,n\%m+m)=mex{SG(m,n\%m)}),所以这个时候(SG(m,n\%m+m)=0),于是(SG(n,m)=1)

    如果(SG(m,n\%m)=0),那么(SG(m,n\%m+m)=1),所以非常显然(SG(n,m)=1)

    但是这一切的前提就是(SG(m,n\%m+m))存在,如果(m<=2*n),那么(SG(n,m))就直接等于(SG(m,n\%m))了,也就是(SG(n,m)=SG(m,n\%m)igoplus1)

    于是一个类似于(gcd)的迭代就好了

    代码

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define LL long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    inline LL read()
    {
    	char c=getchar();
    	int x=0;
    	while(c<'0'||c>'9')	c=getchar();
    	while(c>='0'&&c<='9')
    		x=(x<<3)+(x<<1)+c-48,c=getchar();
    	return x;
    }
    int T;
    LL n,m;
    inline int SG(LL n,LL m)
    {
    	if(!m) return 0;
    	if(n>=m*2) return 1;
    	return 1^SG(m,n%m);
    }
    int main()
    {
    	T=read();
    	while(T--)
    	{
    		n=read(),m=read();
    		if(SG(max(n,m),min(n,m))) puts("Stan wins");
    			else puts("Ollie wins");
    	}
    	return 0;
    }
    
  • 相关阅读:
    vijos1746 floyd
    总结
    用javascript代码拼html
    异步编程学习
    SELECT
    设计 Azure SQL 数据库,并使用 C# 和 ADO.NET 进行连接
    H2数据库
    ASP.NET 文档
    ASP.NET MVC
    ASP.NET Core 中的 Razor 页面介绍
  • 原文地址:https://www.cnblogs.com/asuldb/p/10205759.html
Copyright © 2011-2022 走看看