Codeforces
来源:互联网 发布:linux系统基础教程 编辑:程序博客网 时间:2024/05/30 04:38
Gambling Nim
题目链接
分类:
bitmask
math
matrices
probabilities
1.题意概述
- 给你
n(1≤n≤500000) 张卡片,每张卡片的两个面(正面ai 反面bi )都有写数字,每个面都有0.5的概率正面,卡牌正反面的概率相互独立,求把所有卡牌正面数字(ci=ai or bi )拿来玩Nim游戏,先手必胜的概率。
2.解题思路
什么是Nim游戏:
有若干堆石子,每堆石子的数量都是有限的,合法的移动是“选择一堆石子并拿走若干颗(不能不拿)”,如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。
Nim游戏结论:所有数字异或和为0,先手必败。
因此,这个问题实际上是让我们计算有多少种情况使得所有正面朝上的数字异或和为0。我们不妨假设
S=a1⊕a2⊕...⊕an 并且ci=ai⊕bi ,假设卡片j1,j2,...jk 都是bi 朝上,剩下卡片都是ai 朝上,那么现在总的异或和就是S⊕cj1⊕cj2⊕...⊕cjk ,我们目标就是要找到一些ci 的子集,使得他们的异或和为S (因为一个数与自身异或为0),又因为ci=(ci⊕cj)⊕cj ,因此我们可以自由通过用ci⊕cj 来代替cj (因为ci⊕cj=ci⊕(ci⊕cj) !),因此我们考虑如何简化ci 集合:- 选择出二进制位某一个位为1的数
ci 。 - 使用
ci⊕cj 来替换所有的ci 。 - 重复上述步骤。
最终,我们会得到包括k个0和n-k个数的集合,下面问题在于如何检测这个集合是不是
S 的集合?我们可以按数位来讨论,而所有子集的数量一定是2k 对于每个n−k 个不是零的数字概率就是2k2n ,这是先手必败,那么先手必胜就是2n−k−12n−k ,因为是减一,所以分数一定是最简的,无需化简!- 选择出二进制位某一个位为1的数
3.AC代码
int cnt;ll a[maxn], b[maxn], c[maxn],digit[110];bool add(ll x) { rep(i, 1, cnt + 1) if ((digit[i] ^ x) < x) x = digit[i] ^ x; if (x) { digit[++cnt] = x; return 1; } return 0;}inline void solve() { int n; scanf("%d", &n); ll res = 0; rep(i, 1, n + 1) { scanf("%I64d%I64d", &a[i], &b[i]); c[i] = a[i] ^ b[i]; add(c[i]); res ^= a[i]; } if (add(res)) puts("1/1"); else { ll ans = 1LL << cnt; printf("%I64d/%I64d\n", ans - 1, ans); }}
阅读全文
0 0
- codeforces~~~
- Codeforces
- codeforces
- Codeforces
- codeforces
- codeforces
- Codeforces
- Codeforces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- ACM_字典树模板
- 初识nodejs16
- Mac安装zsh&oh my zsh
- jq获得焦点focus,失去焦点blur,change()函数,js的onfocus,onblur,onchange()方法
- 树状数组模板
- Codeforces
- leetcode 234. Palindrome Linked List
- 【干货】python爬取《战狼2》电影短评论,生成图云
- 操作系统实验七实验报告
- vsftpd服务器不显示文件
- Python初步了解(七)
- Codeforces 853C Star sky(二维前缀和)
- 商场推出幸运抽奖活动
- Technology && Tools AllCodeRows