Alice and Bob (SG函数)
题目
Problem Description
给出一颗满二叉树,以及每个树节点上的石头数量
A和B轮流操作,每次选择一个节点,将其上的任意个石头推向它的儿子
不能不推,若选择的节点为叶节点,则被推的石头消失
A先手,要求输出在保证A必胜的前提下,A第一步有多少种走法
多组数据
Input
第一行一个T,表示数据组数
每组数据先给出一个数n,表示二叉树有n层
接下来有n行,第i行有2^(i-1)个数,表示每个树节点上的石头数量
T<=20,n<=15,其余的数<=10000000
Output
对每组数据输出一个数,表示有多少种走法
Sample Input
4
1
1
2
1
0 0
3
1
2 2
4 4 4 4
4
13
19 13
13 0 9 8
5 4 6 11 2 16 18 6
Sample Output
1
0
6
7
部分样例解释:
为方便理解已将每组数据隔开
将节点从上到下,从左到右依次编号
第一组仅有一种可能走法,即把一号点的一个石子下推
第二组A没有必胜策略,故走法为0
第三组的六种走法分别为
1~2:把一号点的石头下推,共两种
3~6:把二或三号点的石头下推一个,共四种
Problem Source
玲珑杯 Round #9
分析
- 看完题,应该可以想到这也是一道SG函数题:可以把这课满二叉树上每个节点都看作一堆石子
- 不过我们会发现,标准的SG函数要求是每一堆石子都只减不增,可这道题里面除了最下面那一层的石子推完后会消失,其他地方的石子都会转移到下一层的节点上,这就意味着某一堆(不在最下面一层)减少了石子,就一定会有一堆(是这一堆的某个儿子节点)的石子数增加。
- 再想一想,就会想到,实际上我们可以把这棵树分成两部分:奇数层和偶数层,这样对于奇偶性相同的每一层,我们可以把它们看成只减不增的(若某人推了些石子到某个节点,那么你可以把它们推到下一层(奇偶性就不同了))。
- 题目要求求出先手想赢,第一步有多少种方案,我们就可以想象成移掉某个节点之后,再开始游戏,此时就是要求后手(即原来的先手)赢了。也就是说,先求出一个给定奇偶性(我的程序中选的是与最底层奇偶相同的层)层上的节点SG值的抑或值,再枚举那个奇偶性的层上所有节点,看看它的SG值改成几可以满足抑或值为0。
- 注意一下,每个节点对答案的贡献有两类情况:
# | 情况 | 讨论 | 操作 |
---|---|---|---|
1 | 当前节点需要增加石子数 | 那么肯定是从它的父节点推下来的石子 | 要是它父节点石子足够多,那么答案+1 |
2 | 当前节点需要减少石子 | 那么肯定是把当前节点的石子推到它的儿子节点 | 要是它在最底层,那么答案+1;否则+2(两个儿子节点都可以推) |
- 对了有一点很重要,由于每个节点石头可以推走任意个,所以对于每个石头数
n
,不难看出 \(SG(n)=n\) ,所以程序里我就直接把 SG[a[k]] 写成 a[k]了。
程序
#include <cstdio>
#define For(x) for (int k=1<<(x-1),o=1<<x; k<o; k++) //枚举第x层的节点 k
int a[100000],n,T,s,ans; //s:所有节点SG函数的抑或值 int main(){scanf("%d",&T);while (T--){s=0,ans=0;scanf("%d",&n);for (int i=1,o=1<<n; i<o; i++) scanf("%d",&a[i]);for (int i=n; i>0; i-=2) For (i) s^=a[k];for (int i=n; i>0; i-=2) For (i){int aim=s^a[k]; //此节点SG函数需要被改成 aimif (aim<a[k]) ans+=(i==n ? 1:2);//需要减少时,要是是最底层的节点那就只有一个贡献(只能将石头"推下悬崖"),否则有两个贡献(左右儿子) else if (aim>a[k] && a[k>>1]>=aim-a[k]) ans+=1;//需要增加时,只有它的父节点有足够的石子移给这,才对答案有贡献 }printf("%d\n",ans);}return 0;
}
转载于:https://www.cnblogs.com/hehepig/p/6685718.html
Alice and Bob (SG函数)相关推荐
- Trie树合并 + SG函数 ---- BZOJ4730. Alice和Bob又在玩游戏(动态开点Trie 树上全局异或标记 + 合并 + 博弈论)
题目大题 题目大意: 解题思路: 首先我们对于子树u的SG函数为SG函数为SG函数为 ⨁是异或和\bigoplus是异或和⨁是异或和 SG[u]=mex{⨁w∈(w的父亲在u到v的路径上)SG[w]∣ ...
- 2021牛客暑期多校训练营1 A.Alice and Bob 博弈 SG函数
传送门 文章目录 题意: 思路: 题意: 有两堆石子,两个人每次可以进行如下操作:从某一堆狮子中拿出x(x>0)x(x>0)x(x>0)个,从另一堆石子中拿出s∗x(s>=0) ...
- 一类SG函数递推性质的深入分析——2018ACM陕西邀请赛H题
题目描述 定义一种有根二叉树\(T(n)\)如下: (1)\(T(1)\)是一条长度为\(p\)的链: (2)\(T(2)\)是一条长度为\(q\)的链: (3)\(T(i)\)是一棵二叉树,它的左子 ...
- jzoj4024-石子游戏【SG函数,博弈论】
正题 大意 有n堆石头,每堆石头有aiaia_i个每次可以拿走一堆或者Y个(仅当gcd(Y,ai)=1gcd(Y,ai)=1gcd(Y,a_i)=1).拿走最后一堆石头的人就赢了,两个人都是聪明绝顶的 ...
- HDU2999 Stone Game, Why are you always there?【SG函数】
Stone Game, Why are you always there? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/327 ...
- 【acm 博弈论 】 之 Nim游戏与sg函数
文章目录 前言 巴什博弈 威佐夫博弈 Nim游戏 Nim游戏与sg函数 题目 题意 样例 思路 代码 前言 从今天开始复习和整理下acm的部分模块,从博弈论开始. 著名的"取石子" ...
- hdu 5708 Alice and Bob(尼姆博弈)
题目链接:hdu 5708 Alice and Bob Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65535/65536 K (Java ...
- 博弈论与 sg 函数
博弈论 定义 必胜状态 为 先手必胜的状态 , 必败状态 为 先手必败的状态 . 通过推理,我们可以得出下面三条定理: 定理 1:没有后继状态的状态是必败状态. 定理 2:一个状态是必胜状态当且仅当存 ...
- (转载)--SG函数和SG定理【详解】
在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正 ...
最新文章
- hihocoder1260,1261 (HASH经典题)
- 统一的Ajax提交封装,一劳永逸好工具(带跨域处理)
- Informix数据库安装配置
- ARC和MRC混合使用
- 连接linux工具Mtr,Linux/Windows MTR工具检测服务器性能详细方法
- Qt中QTableView应用
- 软件设计师考试真题链接
- 不积跬步无以至千里,反思
- 计算机网络按覆盖地域分为,计算机网络按其所覆盖的地域范围一般可分为________ 。...
- 我的世界服务器ess配置信息,我的世界ess指令大全及用法详解
- 数据中心解决方案安全技术
- 【​观察】英特尔傲腾DC P4800X有哪些适用场景?
- 如何将Excel表格中的数据粘贴到记事本中,且每列间距都为一个空格?
- 70个居家做饭小技巧
- /etc/ssh/ssh_config line 59: Unsupported option “gssapiauthentication“
- 更改ubuntu默认文件管理器为deepin
- 很遗憾未能成功连接服务器神武,神武十年《见证》逍遥游戏里的超级学霸 最希望被别人抄“作业”...
- artemis mq配置开机启动 (centos7)(artemis Init Script)
- 基于 Metal 框架的 GPU 计算
- leetcode17题 电话号码的字母组合