zoukankan      html  css  js  c++  java
  • bzoj 3576: [Hnoi2014]江南乐

    Description

    小A是一个名副其实的狂热的回合制游戏玩家。在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏。 游戏的规则是这样的,首先给定一个数F,然后游戏系统会产生T组游戏。每一组游戏包含N堆石子,小A和他的对手轮流操作。每次操作时,操作者先选定一个不小于2的正整数M (M是操作者自行选定的,而且每次操作时可不一样),然后将任意一堆数量不小于F的石子分成M堆,并且满足这M堆石子中石子数最多的一堆至多比石子数最少的一堆多1(即分的尽量平均,事实上按照这样的分石子万法,选定M和一堆石子后,它分出来的状态是固定的)。当一个玩家不能操作的时候,也就是当每一堆石子的数量都严格小于F时,他就输掉。(补充:先手从N堆石子中选择一堆数量不小于F的石子分成M堆后,此时共有N+M-1)堆石子,接下来小A从这N+M-1堆石子中选择一堆数量不小于F的石子,依此类推。
    小A从小就是个有风度的男生,他邀请他的对手作为先手。小A现在想要知道,面对给定的一组游戏,而且他的对手也和他一样聪明绝顶的话,究竟谁能够获得胜利?

    Solution

    (SG[x]=mex(SG[u])),其中 (u)(x) 的所有子状态
    这题的子状态是取决于 (m)
    我们枚举 (m) 就行了
    知道了 (m) 之后,由于 (max-min<=1) 所以分法是确定的
    也就是先分出 (lfloorfrac{i}{m} floor) ,然后再分别把 (i\%m) 分配给前面长度为 (lfloorfrac{i}{m} floor) 的,使得其变为 (lfloorfrac{i}{m} floor+1)
    这样就可以做 (O(n^2))

    考虑优化:
    我们发现,(lfloorfrac{i}{m} floor) 是可以数论分块的,然后就可以做 (O(n*sqrt{n})) 的了
    注意一个细节:
    虽然 (lfloorfrac{i}{m} floor) 的值是一样的,但是在同一个块中,他们的 (imod m) 可以不同
    但是我们只关心其奇偶性,并且在同一个块内,取模后的值是以 (frac{i}{m}) 为等差数列的值
    我们只需要把块 ([l,r]) 中的 (l+1) 再代进去就好了

    最后把所有 (SG[a[i]]) 异或起来,不为 (0) 就是先手必胜,否则先手必败

    #include <bits/stdc++.h>
    using namespace std;
    const int N=100010;
    int n,SG[N],T,F,d[N];
    void priwork(){
    	for(int i=F,t,w;i<N;i++){
    		for(int j=2,r;j<=i;j=r+1){
    			r=i/(i/j);
    			t=i%j;w=0;
    			if((j-t)&1)w^=SG[i/j];
    			if(t&1)w^=SG[i/j+1];
    			d[w]=i;
    
    			if(j<r){
    				t=i%(j+1);w=0;
    				if((j+1-t)&1)w^=SG[i/j];
    				if(t&1)w^=SG[i/j+1];
    				d[w]=i;
    			}
    		}
    		for(int j=0;j<N;j++)
    			if(d[j]!=i){SG[i]=j;break;}
    	}
    }
    inline void work(){
    	int ans=0,x;
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)scanf("%d",&x),ans^=SG[x];
    	printf("%d ",ans!=0);
    }
    int main()
    {
    	freopen("pp.in","r",stdin);
    	freopen("pp.out","w",stdout);
    	cin>>T>>F;
    	priwork();
    	while(T--)work();
    	return 0;
    }
    
    
  • 相关阅读:
    HDOJ 2011
    OpenCV学习笔记(1)——VS2010 下安装OpenCV 2.4.4安装
    OC——Foundation—常用的类(2)----NSArray
    OC——Foundation—常用的类(1)字符串(NSString)
    OC——Foundation—结构体
    OC----Block语法
    OC----protocol语法
    OC----初识
    OC----内存管理
    OC----Category语法
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8604216.html
Copyright © 2011-2022 走看看