Game of CS 题解
前言
题意简述
Jolly 和 Emily 在玩一个游戏。游戏在一棵编号为 \([0, n-1]\) 的有根树上进行,根节点是 \(0\),每条边都有一个长度,初始所有边都没有颜色。
玩家只能经过没有被完全染色的边。在一次操作中,从根节点出发,在所能到达的边集中选择一条边,并将其染上 \(1\) 单位长度的颜色。不能进行染色的玩家则输掉这个游戏。
Emily 先手,假设他们都采取最优策略,请问谁会赢?
题目分析
公平游戏,考虑求 SG 函数,设 \(\operatorname{SG}(yzh)\) 表示以 \(yzh\) 为根的子树的 SG 函数。答案就是求 \(\operatorname{SG}(root)\)。
对于叶子节点 \(yzh\),后继状态是空集,有 \(\operatorname{SG}(yzh) = 0\)。
考虑非叶子节点 \(yzh\),对于她的每一个孩子 \(xym\),\(yzh\)、\(yzh\) 到 \(xym\) 的边和以 \(xym\) 为根的子树都能构成一棵树,求解这些树的 SG 函数是互不相关的子问题,所以 \(\operatorname{SG}(yzh)\) 便是这些子问题的 SG 函数的 Nim 和。
那么只需考虑往 \(xym\) 这一棵子树上加上其与 \(yzh\) 之间的边对 SG 函数的影响。设这条边的长度为 \(l\)。
当 \(l = 1\) 时,我们有子问题的 SG 函数值为 \(\operatorname{SG}(xym) + 1\)。考虑以下证明。
证明:
首先发现对于 \(\operatorname{SG}(xym) = k\) 等价于 \(xym\) 下面接了 \(k\) 条边权为 \(1\) 的边。因为类似 Nim 游戏,如果后手把 \(\operatorname{SG}(xym)\) 增加,那么先手一定有办法把 \(\operatorname{SG}(xym)\) 变回原来的值。所以操作后 \(\operatorname{SG}(xym)\) 只能减少,相当于在 \(k\) 条边中选一个位置截断。
所以在子问题基础上增加一条边,其 SG 函数值也会增加 \(1\)。
故结论成立。
接下来考虑 \(l > 1\) 的情况。经过手玩,容易发现规律。这里先给出结论:子问题 SG 函数值为 \(\operatorname{SG}(xym) \operatorname{xor} \left (l \bmod 2 \right )\)。以下是证明:
证明:
\(l = 2\) 时,归纳 \(\operatorname{SG}(xym)\),结论显然成立。
接下来假设 \(l = k - 1\) 时结论成立,其中 \(k \bmod 2 = 1\),下证 \(l = k\) 时结论成立。
对于 \(\operatorname{SG}(xym) = 0\) 时,显然成立。假设对于 \(\operatorname{SG}(xym) \leq p - 1\) 均成立,下证对于 \(\operatorname{SG}(xym) = p\) 成立。
先手若给这条边染色,则根据假设,后继局面的 SG 函数为 \(\operatorname{SG}(xym) \operatorname{xor} \left ((k - 1) \bmod 2 \right ) = \operatorname{SG}(xym)\)。
先手若改变 \(\operatorname{SG}(xym)\) 为 \(\operatorname{SG}(xym)' \in [0, \operatorname{SG}(xym) - 1]\)。根据假设,子问题的 SG 函数为 \(\operatorname{SG}(xym)' \operatorname{xor} 1\)。若 \(\operatorname{SG}(xym) \bmod 2=0\),\(\operatorname{SG}(xym)' \operatorname{xor} 1 \in [0, \operatorname{SG}(xym) - 1]\);反之,\(\operatorname{SG}(xym)' \operatorname{xor} 1 \in [0, \operatorname{SG}(xym) - 2] \cup \lbrace \operatorname{SG}(xym) \rbrace\)。
综合两种情况,若 \(\operatorname{SG}(xym) \bmod 2=0\),子问题 SG 函数值为 \(\operatorname{mex} \lbrace \operatorname{SG}(xym) \rbrace \cup [0, \operatorname{SG}(xym) - 1] = \operatorname{mex} [0, \operatorname{SG}(xym)] = \operatorname{SG}(xym) + 1\);反之,子问题 SG 函数值为 \(\operatorname{mex} \lbrace \operatorname{SG}(xym) \rbrace \cup [0, \operatorname{SG}(xym) - 2] \cup \lbrace \operatorname{SG}(xym) \rbrace = \operatorname{mex} [0, \operatorname{SG}(xym) - 2] = \operatorname{SG}(xym) - 1\)。
发现子问题的 SG 函数值恰好是 \(\operatorname{SG}(xym) \operatorname{xor} 1\)。故此时结论成立。
类似地,接下来假设 \(l = k - 1\) 时结论成立,其中 \(k \bmod 2 = 0\),下证 \(l = k\) 时结论成立。
对于 \(\operatorname{SG}(xym) = 0\) 时,显然成立。假设对于 \(\operatorname{SG}(xym) \leq p - 1\) 均成立,下证对于 \(\operatorname{SG}(xym) = p\) 成立。
先手若给这条边染色,则根据假设,后继局面的 SG 函数为 \(\operatorname{SG}(xym) \operatorname{xor} \left ((k - 1) \bmod 2 \right ) = \operatorname{SG}(xym) \operatorname{xor} 1\)。
先手若改变 \(\operatorname{SG}(xym)\) 为 \(\operatorname{SG}(xym)' \in [0, \operatorname{SG}(xym) - 1]\)。根据假设,子问题的 SG 函数为 \(\operatorname{SG}(xym)' \operatorname{xor} 0 = \operatorname{SG}(xym)'\)。
综合两种情况,无论 \(\operatorname{SG}(xym)\),子问题的 SG 函数值均为 \(\operatorname{SG}(xym)\),也即 \(\operatorname{SG}(xym) \operatorname{xor} 0\)。故结论成立。
综上所述,子问题 SG 函数值为 \(\operatorname{SG}(xym) \operatorname{xor} \left (l \bmod 2 \right )\) 对于所有 \(l \geq 2\) 均成立。证毕。
有了这般证明,代码使用一次深搜维护每个点的 SG 函数就行了。
代码实现
在洛谷上目前只有我一个人过,所以妥妥的 Rank1。
// #pragma GCC optimize(3)
// #pragma GCC optimize("Ofast", "inline", "-ffast-math")
// #pragma GCC target("avx", "sse2", "sse3", "sse4", "mmx")
#include <iostream>
#include <cstdio>
#define debug(a) cerr << "Line: " << __LINE__ << " " << #a << endl
#define print(a) cerr << #a << "=" << (a) << endl
#define file(a) freopen(#a".in", "r", stdin), freopen(#a".out", "w", stdout)
#define main Main(); signed main(){ return ios::sync_with_stdio(0), cin.tie(0), Main(); } signed Main
using namespace std;
#include <cstring>
#include <vector>
int cas, n, sg[1010];
vector<pair<int, int> > edge[1010];
void dfs(int now, int fa){
for (const auto & [to, len]: edge[now]) if (to != fa){
dfs(to, now);
if (len == 1) sg[now] ^= sg[to] + 1;
else sg[now] ^= sg[to] ^ (len & 1);
}
}
void solve() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) edge[i].clear(), sg[i] = 0;
for (int i = 1, u, v, w; i <= n - 1; ++i){
scanf("%d%d%d", &u, &v, &w), ++u, ++v;
edge[u].push_back(make_pair(v, w));
edge[v].push_back(make_pair(u, w));
}
dfs(1, 1314520736);
printf("Case %d: ", ++cas);
puts(sg[1] ? "Emily" : "Jolly");
}
signed main() {
int t; scanf("%d", &t);
while (t--) solve();
return 0;
}
Game of CS 题解的更多相关文章
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- JSOI Round 2题解
强行一波题解骗一个访问量好了... http://blog.csdn.net/yanqval/article/details/51457302 http://absi2011.is-programme ...
- 5059 一起去打CS
5059 一起去打CS 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 早就和lyk约好了去 ...
- 2017 google Round C APAC Test 题解
题解参考网上的答案,以及我自己的想法. 主要参考网站:http://codeforces.com/blog/entry/47181,http://codeforces.com/blog/entry/4 ...
- CS Round#53 C Histogram Partition
题意:给定一个数组A,以及一个初始值全为0的空数组B,每次可以对数组B的任意一个区间内的所有数+x,问至少几次操作能把B数组变成A数组 NOIP原题(积木大赛)升级版,话说CS怎么那么多跟NOIP原题 ...
- 2016广东工业大学新生杯决赛网络同步赛暨全国新生邀请赛 题解&源码
Problem A: pigofzhou的巧克力棒 Description 众所周知,pigofzhou有许多妹子.有一天,pigofzhou得到了一根巧克力棒,他想把这根巧克力棒分给他的妹子们.具体 ...
- 算法(第四版)C# 习题题解——3.1
写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更方便的版本见:https ...
- 算法(第四版)C# 习题题解——2.5
写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更方便的版本见:https ...
- 算法(第四版)C# 习题题解——2.4
写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更方便的版本见:https ...
- 算法(第四版)C# 习题题解——2.3
写在前面 整个项目都托管在了 Github 上:https://github.com/ikesnowy/Algorithms-4th-Edition-in-Csharp 查找更为方便的版本见:http ...
随机推荐
- C# 设置PDF表单不可编辑、或提取PDF表单数据
PDF表单是PDF中的可编辑区域,允许用户填写指定信息.当表单填写完成后,有时候我们可能需要将其设置为不可编辑,以保护表单内容的完整性和可靠性.或者需要从PDF表单中提取数据以便后续处理或分析. 之前 ...
- uni-app apple store 上传新版本审核被拒绝 Guideline 5.1.1
- Legal - Privacy - Data Collection and Storage We noticed that your app requests the user's consent ...
- Python 安装 matlabengin 时遇到报错:setup.py install is deprecated. !! 以及 Cannot update time stamp of directory 'dist\matlabengine.egg-info' 的解决方案
目录 Python 安装 matlabengin 时遇到报错:setup.py install is deprecated. !! 以及 Cannot update time stamp of dir ...
- BST-splay板子 - 维护一个分裂和合并的序列
splay 均摊复杂度 \(O(\log n)\) 证明: https://www.cnblogs.com/Mr-Spade/p/9715203.html 我这个 splay 有两个哨兵节点,分别是1 ...
- LeetCode11. 盛最多水的容器题解
LeetCode11. 盛最多水的容器题解 题目链接: https://leetcode.cn/problems/container-with-most-water 示例 思路 暴力解法 定住一个柱子 ...
- Wireshark抓包分析理解DHCP协议及工作流程
一.DHCP简介 DHCP(Dynamic Host Configuration Protocol)动态主机配置协议,前身是BOOTP协议.在大型局域网中,需要给很多主机配置地址信息,如果采用传统 ...
- .NET 文件上传服务设计
.NET文件上传服务设计 前言 在b站学习了一个后端小项目,然后发现这个文件上传设计还挺不错,来实现讲解一下. 项目结构如下: 基于策略+工厂模式实现文件上传服务 枚举 在Model层创建即可 pub ...
- Java 把多个音频拼接成一个
在Java中,将多个音频文件拼接成一个通常需要使用一些专门的音频处理库,因为Java标准库并不直接支持音频文件的合并.一个常用的库是JAVE2(Java Audio Video Encoder)或JL ...
- 3568F-PCIe 5G通信测试手册
- mermaid语法画图
mermaid 脚本语言 graph TB 从上到下 graph BT 从下到上 graph RL 从右到左 graph LR 从左到右 graph LR; A001-->B001; graph ...