zoukankan      html  css  js  c++  java
  • 【BZOJ3576】江南乐(博弈论)

    【BZOJ3576】江南乐(博弈论)

    题面

    BZOJ
    洛谷

    题解

    无论一堆石头怎么拆分,都并不能改变它是一个(Multi-SG)的事实。
    既然每一组的(F)都是固定的,那么我们预处理所有的可能的堆,而将石子拆分成若干堆,也只需要考虑(SG)函数的值就好了。
    但是这样子求(SG)值的复杂度是(O(V^2))的,其中(V)是值域,也就是(10^5)
    再分析一下,将(x)个式子拆分成的最少的石子个数是([x/m]),最多的情况是([x/m+1])
    因为([x/m])可以数论分块,而对于(SG)函数值的影响之和奇偶性相关,所以只需要考虑([x/m],[x/m+1])出现次数的奇偶性一共(4)中情况考虑。
    ([x/m])个数的奇偶性只和(m)相关,([x/m+1])个数的奇偶性只和(x\%m)相关,而(x\%m=x-m[x/m])
    ([x/m])在数论分块中是定值,不需要额外考虑,那么只需要考虑(m)的奇偶性就好啦。
    然而预处理的话复杂度比较爆炸,毕竟我们不一定所有的值都会被用到,那么就写一个记忆化搜索。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define MAX 100100
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    int SG[MAX],vis[MAX];
    int getSG(int x)
    {
    	if(~SG[x])return SG[x];
    	for(int i=2,k;i<=x;i=k+1)
    	{
    		k=x/(x/i);
    		for(int j=i;j<=min(i+1,k);++j)
    		{
    			int s=0;
    			if((x%j)&1)s^=getSG(x/j+1);
    			if((j-x%j)&1)s^=getSG(x/j);
    			vis[s]=x;
    		}
    	}
    	for(int i=0;;++i)if(vis[i]!=x)return SG[x]=i;
    }
    int main()
    {
    	int T=read(),F=read();
    	memset(SG,-1,sizeof(SG));
    	for(int i=0;i<F;++i)SG[i]=0;
    	while(T--)
    	{
    		int n=read(),s=0;
    		while(n--)s^=getSG(read());
    		printf("%d ",(bool)s);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    基于Windows Mobile 5.0的GPS应用程序开发
    iis6应用程序池被自动禁用问题 应用程序池'DefaultAppPool' 被自动禁用
    Axapta物流模块深度历险(八)
    AX的报表服务器(一)
    AX的企业门户(一)
    SQL Server2005 Reporting Services 管理站点
    SQL Server2005 Reporting Services的卸载
    耐心的解决问题
    危险操作符
    慢慢的坚持啊
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9494360.html
Copyright © 2011-2022 走看看