\(\mathcal{Decription}\)

  Link.

  定义一棵圣诞树:

  • 是仙人掌。

  • 不存在两个同一环上的点,度数均 \(\ge 3\)。

  给出 \(n\) 棵互不相关的圣诞树,双人博弈,每轮切断一棵圣诞树的一条边,并且与该树根不向连的部分全部消失,不能操作者负。求先手是否有必胜策略。

  多测,\(T,n\le 100\),\(m\le 500\)。

\(\mathcal{Solution}\)

  没有什么不说人话的定理和结论,这里只应用 SG 函数和 Nim 游戏的基础知识。

  本题解中,定义树上“长度”为两点间边的数量。

  首先,考虑从根连出多条链的图,显然是 Nim 游戏,每堆石子就是链的长度,根的 SG 函数为这些长度的异或和。


  接下来考虑任意一棵树,发现上述结论可以归纳地推广。根据定义,全局 SG 函数为各部分独立 SG 函数异或和,得到:

\[ \operatorname{sg} (u)=\bigoplus_{v\in son_u} (\operatorname{sg} (v)+1)
\]

  注意这里 \(\operatorname{sg} (u)\) 实际上表示 \(u\) 子树的 SG 函数值。其中 \(+1\) 意为每堆石子(链)的长度都 \(+1\)。


  回忆一下 SG 函数的定义:

\[ \operatorname{sg} (S)=\operatorname{mex}_{T\in\operatorname{next}(S) }\{\operatorname{sg} (T)\}\tag{*}
\]

  此后,考虑从 \((*)\) 式的角度求环的 SG 函数。环的后继状态为删除环上任意一条边得到两条链,而链是 Nim 游戏,SG 函数为链长异或和,可以解决。形式地,设环 \(C\) 的大小为 \(n\),有:

\[ \operatorname{sg} (C)=\operatorname{mex}_{a+b=n-1\land(a,b\in\mathbb N)}\{a\oplus b\}
\]

  分 \(n\) 的奇偶性讨论:

  1. \(2|n \Rightarrow 2\not|(n-1)\),而 \(a+b=n-1\),所以 \(a,b\) 奇偶性不同,则它们二进制最低位不同。那么两数异或值不可能为 \(0\),即集合中不存在 \(0\),那么此时 \(\operatorname{sg} (C)=0\)。

  2. \(2\not|n \Rightarrow 2|(n-1)\),而 \(a+b=n-1\),同理地,两数异或值必然为偶数,而且显然存在 \(0\)。得到 \(\operatorname{sg} (C)=1\)。

  综上,\(\operatorname{sg} (C)=[2\not|n]\)。


  回到本题,“圣诞树”的定义保证了环在缩点后的图中是叶子,所以对于环,用环的 SG 函数算,否则用树的 SG 函数算,最后求每棵圣诞树的 SG 异或就能判断先手胜负啦。

  单棵树复杂度 \(\mathcal O(n)\)。

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>

const int MAXN = 100, MAXM = 500;
int n, m, ecnt, head[MAXN + 5], dep[MAXN + 5], sg[MAXN + 5];
bool vis[MAXN + 5]; struct Edge { int to, nxt; } graph[MAXM * 2 + 5]; inline void link ( const int s, const int t ) {
graph[++ ecnt] = { t, head[s] };
head[s] = ecnt;
} inline int calcSG ( const int u, const int fe ) {
/*
返回值表示当前找到的环的顶点(唯一可能度数 >= 3 的点),若不在环上,返回 0。
*/
vis[u] = true;
for ( int i = head[u], v, cir; i; i = graph[i].nxt ) {
if ( ( i ^ 1 ) == fe || !( v = graph[i].to ) ) continue;
if ( vis[v] ) {
sg[v] ^= ( dep[u] - dep[v] + 1 ) & 1;
graph[i ^ 1].to = 0;
return v;
}
dep[v] = dep[u] + 1, cir = calcSG ( v, i );
if ( !cir ) sg[u] ^= sg[v] + 1;
else if ( cir ^ u ) return cir;
}
return 0;
} inline void clear () {
ecnt = 1;
for ( int i = 1; i <= n; ++ i ) head[i] = sg[i] = dep[i] = vis[i] = 0;
} int main () {
for ( int T; ~scanf ( "%d", &T ); ) {
int ans = 0;
while ( T -- ) {
clear ();
scanf ( "%d %d", &n, &m );
for ( int i = 1, u, v; i <= m; ++ i ) {
scanf ( "%d %d", &u, &v );
link ( u, v ), link ( v, u );
}
calcSG ( 1, 0 ), ans ^= sg[1];
}
puts ( ans ? "Sally" : "Harry" );
}
return 0;
}

Solution -「POJ 3710」Christmas Game的更多相关文章

  1. 「POJ 3666」Making the Grade 题解(两种做法)

    0前言 感谢yxy童鞋的dp及暴力做法! 1 算法标签 优先队列.dp动态规划+滚动数组优化 2 题目难度 提高/提高+ CF rating:2300 3 题面 「POJ 3666」Making th ...

  2. Solution -「ARC 104E」Random LIS

    \(\mathcal{Description}\)   Link.   给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...

  3. Solution -「ACM-ICPC BJ 2002」「POJ 1322」Chocolate

    \(\mathcal{Description}\)   Link.   \(c\) 种口味的的巧克力,每种个数无限.每次取出一个,取 \(n\) 次,求恰有 \(m\) 个口味出现奇数次的概率. \( ...

  4. 「POJ Challenge」生日礼物

    Tag 堆,贪心,链表 Solution 把连续的符号相同的数缩成一个数,去掉两端的非正数,得到一个正负交替的序列,把该序列中所有数的绝对值扔进堆中,用所有正数的和减去一个最小值,这个最小值的求法与「 ...

  5. Solution -「CTS 2019」「洛谷 P5404」氪金手游

    \(\mathcal{Description}\)   Link.   有 \(n\) 张卡牌,第 \(i\) 张的权值 \(w_i\in\{1,2,3\}\),且取值为 \(k\) 的概率正比于 \ ...

  6. Solution -「BZOJ 3812」主旋律

    \(\mathcal{Description}\)   Link.   给定含 \(n\) 个点 \(m\) 条边的简单有向图 \(G=(V,E)\),求 \(H=(V,E'\subseteq E)\ ...

  7. Solution -「CF 1342E」Placing Rooks

    \(\mathcal{Description}\)   Link.   在一个 \(n\times n\) 的国际象棋棋盘上摆 \(n\) 个车,求满足: 所有格子都可以被攻击到. 恰好存在 \(k\ ...

  8. 「POJ 3268」Silver Cow Party

    更好的阅读体验 Portal Portal1: POJ Portal2: Luogu Description One cow from each of N farms \((1 \le N \le 1 ...

  9. Solution -「简单 DP」zxy 讲课记实

    魔法题位面级乱杀. 「JOISC 2020 Day4」治疗计划 因为是不太聪明的 Joker,我就从头开始理思路了.中途也会说一些和 DP 算法本身有关的杂谈,给自己的冗长题解找借口. 首先,治疗方案 ...

随机推荐

  1. 利用 Maven 创建 Docker 镜像并且推送到私有注册中心

    利用 Maven 命令生成项目框架 mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -Darchetype ...

  2. PyCharm - 关联mysql失败 - Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property manually.

    时区错误,MySQL默认的时区是UTC时区,比北京时间晚8个小时. 所以要修改mysql的时长 在mysql的命令模式下,输入: set global time_zone='+8:00'; 再次连接成 ...

  3. 微信小程序封装mixins方法

    在app.js中这样引入 import '@src/utils/mixins' mixins函数如下 /** * 封装类似vue的混入功能 */ let native = Page Page = (o ...

  4. uni-app、小程序之swiper-item内容过多显示不全的解决方案

    原文 最近在项目遇到swiper高度不能自适应,导致swiper-item 里面的内容过多时只能显示一部分,最终解决方案: <swiper> <swiper-item> < ...

  5. mybatis(CRUD)

    3.mybatis(CRUD) 有了mybatis,我们要对数据库进行增删改查只需要操作接口和mapper.xml文件,然后进行测试就可以了. 实例代码如下: 接口 public interface ...

  6. 02-JS中的数据类型及类型转换

    02-JS中的数据类型及类型转换 一.数据类型 JS中的值,无论是字面量还是变量,都有明确的类型. (一)概述 1.基本类型5种 number 数字类型 string 字符串类型 boolean 布尔 ...

  7. 一起看看MySQL中的隐藏列

    摘要:在mysql的多版本并发控制mvcc中,我们知道mysql中存在一些隐藏列,例如行标识.事务ID.回滚指针等,不知道大家是否和我一样好奇过,要怎样才能实际地看到这些隐藏列的值呢? 本文分享自华为 ...

  8. golang中的channel

    1. 概念 单纯的将函数并发执行是没有意义的,函数与函数之间需要交换数据才能提现并发执行函数的意义虽然可以使用共享内存来进行数据的交换,但是在共享内存在不同的goroutine中容易发生竟态问题,为了 ...

  9. 洛谷P1002过河卒(60分)

    逻辑没问题,运行超时,得分60 写注释了,不多解释 import java.util.Scanner; public class D1 { static int a,b,c,d,con; //棋盘大小 ...

  10. CaCl2 项目介绍。

    一 是什么? 中国自然语言处理(NLP)研究项目. 二 主要功能? 从互联网获取的大量文本数据,结合自研力量进行分析.将数据重新格式化为大量条目,目录,并根据金融行业分类标准对这些条目进行了分类. 三 ...