【bzoj4730】 Alice和Bob又在玩游戏
http://www.lydsy.com/JudgeOnline/problem.php?id=4730 (题目链接)
题意
给出一个森林,两个人轮流操作,每次把一个节点以及它的祖先全部抹去,无节点可以抹去是算输,问是否存在先手必胜策略。
Solution
trie树合并,其实就是线段树合并。
bzoj4134的简单版:http://blog.csdn.net/werkeytom_ftd/article/details/50958988
细节
二进制小心写错
代码
// bzoj4730
#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=1000010;
int head[maxn],vis[maxn],SG[maxn],rt[maxn],n,m,sz,cnt,bin[30];
struct edge {int to,next;}e[maxn<<1];
struct node {
int ls,rs,tag,size;
void Init() {ls=rs=tag=size=0;}
}tr[maxn<<2]; void link(int u,int v) {
e[++cnt]=(edge){v,head[u]};head[u]=cnt;
e[++cnt]=(edge){u,head[v]};head[v]=cnt;
}
void pushdown(int k,int x) {
if (tr[k].tag&bin[x-1]) swap(tr[k].ls,tr[k].rs);
tr[tr[k].ls].tag^=tr[k].tag;
tr[tr[k].rs].tag^=tr[k].tag;
tr[k].tag=0;
}
void insert(int &k,int x,int y) {
if (!k) k=++sz;tr[k].Init();
tr[k].size=1;if (!y) return;
x&bin[y-1] ? insert(tr[k].rs,x,y-1) : insert(tr[k].ls,x,y-1);
}
int merge(int x,int y,int k) {
if (!x || !y) return x|y;
pushdown(x,k);pushdown(y,k);
tr[x].ls=merge(tr[x].ls,tr[y].ls,k-1);
tr[x].rs=merge(tr[x].rs,tr[y].rs,k-1);
tr[x].size=tr[tr[x].ls].size+tr[tr[x].rs].size+(k==0);
return x;
}
void dfs(int x,int fa) {
int t=0;vis[x]=1; //t表示儿子的SG异或和
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
dfs(e[i].to,x);
t^=SG[e[i].to];
}
insert(rt[x],t,20); //此时插入的是删除x所得到的后继状态的SG值
for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa) {
tr[rt[e[i].to]].tag=t^SG[e[i].to]; //异或上除e[i].to以外其它儿子节点子树的SG
rt[x]=merge(rt[x],rt[e[i].to],20);
}
for (int i=20,p=rt[x];i;i--) {
pushdown(p,i);
if (tr[tr[p].ls].size<bin[i-1]) p=tr[p].ls;
else SG[x]|=bin[i-1],p=tr[p].rs;
}
}
int main() {
bin[0]=1;for (int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
int T;scanf("%d",&T);
while (T--) {
sz=0;cnt=0;
for (int i=1;i<=n;i++) vis[i]=rt[i]=SG[i]=head[i]=0;
scanf("%d%d",&n,&m);
for (int u,v,i=1;i<=m;i++) {
scanf("%d%d",&u,&v);
link(u,v);
}
int ans=0;
for (int i=1;i<=n;i++)
if (!vis[i]) dfs(i,0),ans^=SG[i];
puts(ans ? "Alice" : "Bob");
}
return 0;
}
【bzoj4730】 Alice和Bob又在玩游戏的更多相关文章
- bzoj4730: Alice和Bob又在玩游戏
Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...
- [UOJ266]Alice和Bob又在玩游戏
[UOJ266]Alice和Bob又在玩游戏 Tags:题解 作业部落 评论地址 TAG:博弈 题意 不同于树的删边游戏,删掉一个点删去的是到根的路径 题解 这题只和计算\(SG\)有关,博弈的有关内 ...
- UOJ #266 【清华集训2016】 Alice和Bob又在玩游戏
题目链接:Alice和Bob又在玩游戏 这道题就是一个很显然的公平游戏. 首先\(O(n^2)\)的算法非常好写.暴力枚举每个后继计算\(mex\)即可.注意计算后继的时候可以直接从父亲转移过来,没必 ...
- uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数)
uoj266[清华集训2016]Alice和Bob又在玩游戏(SG函数) uoj 题解时间 考虑如何求出每棵树(子树)的 $ SG $ . 众所周知一个状态的 $ SG $ 是其后继的 $ mex $ ...
- [BZOJ4730][清华集训2016][UOJ266] Alice和Bob又在玩游戏
题意:俩智障又在玩游戏.规则如下: 给定n个点,m条无向边(m<=n-1),保证无环,对于每一个联通块,编号最小的为它们的根(也就是形成了一片这样的森林),每次可以选择一个点,将其本身与其祖先全 ...
- 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 值异或起来检验是否非零即可.注意到我们每删除一个点到根节点的路径后 ...
- UOJ#266. 【清华集训2016】Alice和Bob又在玩游戏 博弈,DSU on Tree,Trie
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ266.html 题解 首先我们可以直接暴力 $O(n^2)$ 用 sg 函数来算答案. 对于一个树就是枚举 ...
- 【清华集训2016】Alice和Bob又在玩游戏
不难的题目.因为SG性质,所以只需要对一棵树求出. 然后如果发现从上往下DP不太行,所以从下往上DP. 考虑一个点对子树的合并,考虑下一个删的点在哪一个子树,那么剩下的状态实际上就是把一个子树所有能达 ...
随机推荐
- 2017-2018-1 20155202 张旭 嵌入式C语言——时钟提取时分秒
2017-2018-1 20155202 张旭 嵌入式C语言--时钟提取时分秒 任务要求: 在作业本上完成附图作业,要认真看题目要求. 提交作业截图 作弊本学期成绩清零(有雷同的,不管是给别人传答案, ...
- zabbix问题之snmp监控端口流量断图
zabbix之snmp监控端口断图问题 在使用zabbix的snmp方式的监控端口流量时,某一个图总是断断续续的(被监控设备有较大的端口流量),经常会出现几分钟内没有图像的问题. 端口流量断图原因: ...
- ASP.NET Core分布式项目实战-目录
前言 今年是2018年,发现已经有4年没有写博客了,在这4年的时光里,接触了很多的.NET技术,自己的技术也得到很大的进步.在这段时光里面很感谢张队长以及其他开发者一直对.NET Core开源社区做出 ...
- flask_admin 笔记二 授权和权限
权限当然就是让有应该权限的用户能执行某些操作,把没有权限的用户限制在外面.Flask-admin提供了几种方法来处理: 1, Http basic Auth 最简单的身份验证形式是HTTP基本身份验证 ...
- Java容器类List、ArrayList、Vector及map、HashTable、HashMap的区别与用法
Java容器类List.ArrayList.Vector及map.HashTable.HashMap的区别与用法 ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数 ...
- Bloom Filter解析
布隆过滤器简介:https://www.cnblogs.com/Jack47/p/bloom_filter_intro.html 布隆过滤器详解:原文链接:http://www.cnblogs.com ...
- 分布式理论:深入浅出Paxos算法
前言 Paxos算法是用来解决分布式系统中,如何就某个值达成一致的算法.它晦涩难懂的程度完全可以跟它的重要程度相匹敌.目前关于paxos算法的介绍已经非常多,但大多数是和稀泥式的人云亦云,却很少有人能 ...
- 01_python2.x和python3.x中range()的区别
Py2.x 1) .range 和xrange都是经常使用的,特别是range()返回一个列表 2) .xrange()一般用来创建迭代对象 Py3.x xrange()不存在了,只有range()而 ...
- Hyperledger Fabric网络节点架构
Fabric区块链网络的组成  区块链网络结构图 区块链网络组成 组成区块链网络相关的节点 节点是区块链的通信主体,和区块链网络相关的节点有多种类型:客户端(应用).Peer节点.排序服务(Orde ...
- IDA Pro 在CSAPP lab2中的使用
在做lab2的时候,偶然的情况下,发现了IDA pro这样一个反汇编工具,总的来说对于lab2这样的小实验读懂代码的大体功能是有作用的,但对于想要具体明白某一条指令的执行过程,又显得不足,到最后还是需 ...