【清华集训2016】Alice和Bob又在玩游戏
不难的题目。因为SG性质,所以只需要对一棵树求出。
然后如果发现从上往下DP不太行,所以从下往上DP。
考虑一个点对子树的合并,考虑下一个删的点在哪一个子树,那么剩下的状态实际上就是把一个子树所有能达到的状态异或上一个数。
此时还有不到子树的状态,直接插入子树SG异或值。
所以显然,就是维护一个支持全部异或,以及状态合并,查询mex的数据结构,直接trie合并带tag就好了。
时空复杂度 \(O(n \log n)\)
#include <bits/stdc++.h>
const int MAXN = 100010;
const int UP = 21;
const int MN = MAXN * (UP + 1);
int son[MN][2], val[MN], tag[MN], txt;
void mktag(int u, int v) { tag[u] ^= v; }
void pushdown(int u, int dig) {
if (tag[u]) {
if (son[u][0]) mktag(son[u][0], tag[u]);
if (son[u][1]) mktag(son[u][1], tag[u]);
if (tag[u] >> dig & 1)
std::swap(son[u][0], son[u][1]);
tag[u] = 0;
}
}
void update(int u) { val[u] = val[son[u][0]] + val[son[u][1]]; }
void insert(int & x, int v, int dig = UP) {
if (!x) x = ++txt, son[x][0] = son[x][1] = val[x] = tag[x] = 0;
if (dig == -1) return (void) (val[x] = 1);
pushdown(x, dig);
insert(son[x][v >> dig & 1], v, dig - 1);
update(x);
}
int merge(int x, int y, int dig = UP) {
if (!x || !y) return x | y;
pushdown(x, dig), pushdown(y, dig);
son[x][0] = merge(son[x][0], son[y][0], dig - 1);
son[x][1] = merge(son[x][1], son[y][1], dig - 1);
if (dig != -1) update(x);
return x;
}
int query(int u, int dig = UP) {
if (!u) return 0;
if (val[son[u][0]] < (1 << dig)) return query(son[u][0], dig - 1);
return query(son[u][1], dig - 1) | 1 << dig;
}
int head[MAXN], nxt[MAXN << 1], to[MAXN << 1], tot;
void addedge(int b, int e) {
nxt[++tot] = head[b]; to[head[b] = tot] = e;
nxt[++tot] = head[e]; to[head[e] = tot] = b;
}
int sg[MAXN], rts[MAXN];
bool vis[MAXN];
int solve(int u, int fa = 0) {
vis[u] = true;
int pre = 0, & rt = rts[u];
for (int i = head[u]; i; i = nxt[i]) if (to[i] != fa)
solve(to[i], u), pre ^= sg[to[i]];
for (int i = head[u]; i; i = nxt[i])
if (to[i] != fa) {
mktag(rts[to[i]], pre ^ sg[to[i]]);
rt = merge(rt, rts[to[i]]);
}
insert(rt, pre);
sg[u] = query(rt);
return rt;
}
int n, m;
int main() {
std::ios_base::sync_with_stdio(false), std::cin.tie(0);
int T; std::cin >> T;
while (T --> 0) {
std::cin >> n >> m;
for (int i = 1; i <= m; ++i) {
int t1, t2; std::cin >> t1 >> t2;
addedge(t1, t2);
}
int ans = 0;
for (int i = 1; i <= n; ++i) if (!vis[i])
solve(i), ans ^= sg[i];
std::cout << (ans ? "Alice" : "Bob") << '\n';
tot = 0; memset(head, 0, n + 1 << 2);
memset(vis, 0, n + 1); txt = 0;
memset(rts, 0, n + 1 << 2);
}
return 0;
}
【清华集训2016】Alice和Bob又在玩游戏的更多相关文章
- uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数)
uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数) uoj 题解时间 考虑如何求出每棵树(子树)的 $ SG $ . 众所周知一个状态的 $ SG $ 是其后继的 $ mex $ ...
- UOJ #266 【清华集训2016】 Alice和Bob又在玩游戏
题目链接:Alice和Bob又在玩游戏 这道题就是一个很显然的公平游戏. 首先\(O(n^2)\)的算法非常好写.暴力枚举每个后继计算\(mex\)即可.注意计算后继的时候可以直接从父亲转移过来,没必 ...
- [UOJ266]Alice和Bob又在玩游戏
[UOJ266]Alice和Bob又在玩游戏 Tags:题解 作业部落 评论地址 TAG:博弈 题意 不同于树的删边游戏,删掉一个点删去的是到根的路径 题解 这题只和计算\(SG\)有关,博弈的有关内 ...
- [BZOJ4730][清华集训2016][UOJ266] Alice和Bob又在玩游戏
题意:俩智障又在玩游戏.规则如下: 给定n个点,m条无向边(m<=n-1),保证无环,对于每一个联通块,编号最小的为它们的根(也就是形成了一片这样的森林),每次可以选择一个点,将其本身与其祖先全 ...
- bzoj4730: Alice和Bob又在玩游戏
Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...
- UOJ#266. 【清华集训2016】Alice和Bob又在玩游戏 博弈,DSU on Tree,Trie
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ266.html 题解 首先我们可以直接暴力 $O(n^2)$ 用 sg 函数来算答案. 对于一个树就是枚举 ...
- uoj#266. 【清华集训2016】Alice和Bob又在玩游戏(博弈论)
传送门 完了我连sg函数是个啥都快忘了 设\(sg[u]\)为以\(u\)为根节点的子树的\(sg\)函数值,\(rem[u]\)表示\(u\)到根节点的路径删掉之后剩下的游戏的异或值 根节点\(u\ ...
- UOJ 266 - 【清华集训2016】Alice和Bob又在玩游戏(SG 定理+01-trie)
题面传送门 神仙题. 首先注意到此题的游戏是一个 ICG,故考虑使用 SG 定理解决这个题,显然我们只需对每个连通块计算一遍其 SG 值异或起来检验是否非零即可.注意到我们每删除一个点到根节点的路径后 ...
- 【bzoj4730】 Alice和Bob又在玩游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=4730 (题目链接) 题意 给出一个森林,两个人轮流操作,每次把一个节点以及它的祖先全部抹去,无节点可 ...
随机推荐
- splite与join
Python split() 通过指定分隔符对字符串进行切片 切片之后为list数据类型. sentence = 'I can because I think I can ' s_1 = senten ...
- pom.xml标签页名称
pom.xml文件双击打开后,标签页显示的名称与<artifactId></artifactId>的内容相一致.
- spark教程(七)-文件读取案例
sparkSession 读取 csv 1. 利用 sparkSession 作为 spark 切入点 2. 读取 单个 csv 和 多个 csv from pyspark.sql import Sp ...
- FullPage.js全屏插件文档及使用方法
简介 fullPage.js是一个基于jQuery的全屏滚动插件,它能够很方便.很轻松的制作出全屏网站 下载地址 下载地址 相关示例:基于fullpage.js实现的360全屏滑动效果 支持功能 支持 ...
- windows下生成zlib1.dll
一.原料: VC zlib-1.2.3-src.zip 二.解压zlib-1.2.3-src.zip,用VC打开工作空间 src/zlib/1.2.3/zlib-1.2.3/projects/visu ...
- 配置Mysql远程连接
一.赋予某个用户权限 1.赋予权限格式:grant 权限 on 数据库对象 to 用户@IP(或者相应正则) 注:可以赋予select,delete,update,insert,index等权限精确到 ...
- c# 转换Image为Icon
/// <summary> /// 转换Image为Icon /// </summary> /// <param name="image">要转 ...
- SDX Instance Resource Assignment Guide 1 of 2
SDX Instance Resource Assignment Guide 1 of 2 Memory and vCPU Requirements for NetScaler VPX https:/ ...
- 这38个小技巧告诉你如何快速学习MySQL数据库
1.如何快速掌握MySQL? ⑴培养兴趣兴趣是最好的老师,不论学习什么知识,兴趣都可以极大地提高学习效率.当然学习MySQL 5.6也不例外.⑵夯实基础计算机领域的技术非常强调基础,刚开始学习可能还认 ...
- thinkphp3.2.3 自定义路由实践
使用了很久的tp3,却没发现还有这么可玩性的功能. 官方文档:要使用路由功能,前提是你的URL支持PATH_INFO(或者兼容URL模式也可以,采用普通URL模式的情况下不支持路由功能),并且在应用( ...