【bzoj3576】 Hnoi2014—江南乐

http://www.lydsy.com/JudgeOnline/problem.php?id=3576 (题目链接)

题意

  给出一个数$F$,然后$n$堆石子,每次操作可以把一堆不少于$F$的石子分成$m$堆,$m$是玩家任选的不少于$2$的正整数,这$m$堆石子中最多的一堆与最少的一堆之差不超过$1$,问是否存在先手必胜。

Solution

  对每一个子游戏考虑如何求解$SG$函数。

  假设当前一堆中有$i$石子,我们想把它分成$j$堆,那么石子数为$k=\lfloor{i/j}\rfloor+1$的有$x=i-j*k$堆,石子数为$k$的有$y=i-x$堆。而此时的$SG[i]=[(x\&1)*SG[k+1]]~XOR~[(y\&1)*SG[k]]$。考虑到$k$的取值只有$\sqrt{i}$种,我们可以枚举$j$,那么怎么确定$x,y$的奇偶性呢。$x$的奇偶性只与$j$有关,而一旦$x$确定,$y$就确定了。所以$x,y$的奇偶性只有$2$种情况,分开讨论一下就好了。

代码

// bzoj3576
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define LL long long
#define inf (1ll<<60)
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std;

const int maxn=100010;
int T,F,n,SG[maxn],v[maxn];

int main() {
	scanf("%d%d",&T,&F);
	for (int i=0;i<F;i++) SG[i]=0;
	for (int i=F;i<=100000;i++) {
		for (int k,pos,j=2;j<=i;j=pos+1) {
			k=i/j;pos=i/k;
			int x=i-k*j,y=j-x;
			v[((x&1)*SG[k+1])^((y&1)*SG[k])]=i;
			if (j+1<=min(pos,i)) {
				x=i-k*(j+1),y=j+1-x;
				v[((x&1)*SG[k+1])^((y&1)*SG[k])]=i;
			}
		}
		for (int j=0;;j++) if (v[j]!=i) {SG[i]=j;break;}
		//printf("%d ",SG[i]);
	}
	while (T--) {
		scanf("%d",&n);
		int ans=0;
		for (int x,i=1;i<=n;i++) {
			scanf("%d",&x);
			ans^=SG[x];
		}
		printf(ans ? "1" : "0");
		if (T) printf(" ");
	}
	return 0;
}
时间: 2024-09-29 03:15:12

【bzoj3576】 Hnoi2014—江南乐的相关文章

bzoj3576[Hnoi2014]江南乐

http://www.lydsy.com/JudgeOnline/problem.php?id=3576 SG函数 我们发现$\left \lfloor \frac{n}{i} \right \rfloor$只有$\sqrt{n}$个取值 不妨设$x=\left \lfloor \frac{n}{i} \right \rfloor$ 那么最终的分割方案一定是下面4种情况之一:偶数个$x$,偶数个$x+1$:偶数个$x$,奇数个$x+1$:奇数个$x$,偶数个$x+1$:奇数个$x$,奇数个$x+

【BZOJ】3576: [Hnoi2014]江南乐

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3576 很显然,这是一个multi-nim游戏. 注意:1.一个点的SG值就是一个不等于它的后继点的SG的且大于等于零的最小整数.(mex) 2.主游戏的SG值等于所有子游戏的异或和 所以区分好主游戏和后继点的区别.   一开始多个石子堆组合起来形成了一个主游戏. 一个石子堆可以分为多个石子堆,每一种分发构成了一个主游戏,这些主游戏的异或和构成的当前这个点(状态)的SG函数.  显然有一个

bzoj 3576: [Hnoi2014]江南乐

Description 小A是一个名副其实的狂热的回合制游戏玩家.在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏. 游戏的规则是这样的,首先给定一个数F,然后游戏系统会产生T组游戏.每一组游戏包含N堆石子,小A和他的对手轮流操作.每次操作时,操作者先选定一个不小于2的正整数M (M是操作者自行选定的,而且每次操作时可不一样),然后将任意一堆数量不小于F的石子分成M堆,并且满足这M堆石子中石子数最多的一堆至多比石子数最少的一堆多1(即分的尽量平均,事

BZOJ 3576 江南乐

http://www.lydsy.com/JudgeOnline/problem.php?id=3576 思路:由于数字巨大,因此N^2异或做法是过不了的,我们考虑将n个石子分成i堆,那么会有n%i堆n/i+1的石子,i-n%i堆n/i的石子.如果两个堆的石子数相同,那么他们异或起来就为0,因此,这两种石子堆,我们可以看做:每种至多只有1堆.这样就可以枚举n/i,然后可以避免计算很多重复的部分,时间复杂度为N^1.5 1 #include<algorithm> 2 #include<cs

专题总结(博弈论)

https://zybuluo.com/ysner/note/1232112 双人平等博弈(理论应用前提) 信息完全公开 双方轮流行动 面对同一局面,双方的决策集合相同 一般来说,规定不能操作者输 游戏局面不会成环,有限步之后游戏必定结束 \(N\)态与\(P\)态 首先把结束的局面置为\(P\)态 对于一个\(P\)态,找到所有能转移到它的状态,它们全部是\(N\)态 搜到一个状态时,它还没有被筛掉,就是\(P\)态 很多题目中, P 态之间不可直接转移. 一些性质 \(SG\)值异或和为\(

总结与心得(持续更新)

不知道为什么,刚学的算法过了2个月就忘得一干二净,我并没有背代码啊,当时学的时候还刷了好多题来着→_→,我是不是大脑能力严重衰退了. 动态规划 单调队列 一般情况下,${dp}$方程可以搞成这样:${f_i=f_j+t_j+t_i}$,只要其中没有变量同时与${i,j}$都有关,那么我们可以用单调队列来做,单调队列里面元素的关键字就是与${j}$有关的东西${f_j+t_j}$.example:生产产品 有些比较特殊的,虽然存在同时与${i,j}$相关的函数,但是这个函数比较简单,使得已经存在在

HNOI 2014

D1T1:画框 frame 题意:给你两个n阶正整数方阵,请你求最大的\( \sum_{i = 1}^{n} A_{i, p_i}\times \sum_{i = 1}^{n} B_{i, p_i}  \)其中\({p_i}\)是一个n的排列.\(n \le 70\). 如果A=B,这就是一个二分图最大完美匹配问题,那么我们可以用费用流或者KM算法解决,然而A却可以不等于B,我们需要另辟蹊径. 当年我看到这道题就只会随机化乱搞,现在看来,如果仔细的思考还是可以搞出来的. 想到,我们可以求出对于A

YCB 的暑期计划

前言 YCB现在很弱(TAT) 暑假有一个月,赶快狂补一下. 大概的计划如下: 首先前期会以数据结构为主,毕竟代码能力太弱,涉及内容:线段树分治.二进制分组.KD-Tree. 等数据结构做到没有智商的时候加入一波数论,内容为 杜教筛.min_25筛. 然后中途小清新一下,做一些 组合博弈与构造题. 接着继续练代码能力,顺便学一些神奇的暴力:启发式合并.dsu on tree . 然后图论也忘的差不多了,就回过头去学点新东西,大概会有spfa判负环.0/1分数规划.差分约束. 估计这个时候也没有什

HNOI2014数据及题解

HNOI2014总结 省选成绩出来了,170分,其中第一天100分,第二天70分,果然和感觉一样,总会有几道题会跪,幸好这才是高一. Day1,一看到第三题就感觉这道题比第一二题好做,但是题目理解错了TAT,一开始竟然脑残到以为这颗树只能是二叉树,于是浪费了一个小时写了一个错误的程序,在检查的时候才发现不一定是二叉树,而且时间只有一个小时了,所以打完50分的算法后就没有去打正解,day1被爆出翔. 第二试,看完题目后觉得只有第一题有点想法,但是由于以前关于字符串的题目都是用pascal写的,所以