牛客多校赛第9场G Game
黑板上有一些数字,Alice和Bob轮流操作,每次操作可以选择黑板上的两个数(两个数可以相同),然后在黑板上写下这两个数的异或。谁先写出k谁赢。
首先重复的数字是没有用的,进而可以推出除整局游戏的第一步之外,都可以选择保持当前的局面不变.
比如如果一个玩家面对的是一个必输的局面,他就可以选择保持局面不变再将这个局面送给对面。
因为这个性质的存在,所以游戏的发展有如下三种情况。
1、 先手一步获胜。
这就要求存在
2、先手无法一步获胜,并且无论先手选择哪两个,后手都可以获胜。
也就是对于任意的都存在,满足
将这个式子的左边两项都异或上k
然后用来代替则有
也就是对于异或操作是封闭的。
也就是等价于,中不同的数字的个数==2^(线性基的维数)
3、先手不能一步获胜,后手也不满足条件,所以两者就会一直僵持下去,最终平局。
#include<algorithm> #include<iostream> using namespace std; const int N = 1e6+10; int n , m , k; int A[N] , B[N] , p[30]; void Solve() { int tmp , pos , num; cin >> n >> k; for(int i = 1 ; i <= n ; ++i) cin >> A[i] , B[i] = A[i]; sort(B + 1 , B + 1 + n); m = unique(B + 1 , B + 1 + n) - B - 1; for(int i = 1 ; i <= n ; ++i) { tmp = A[i] ^ k; pos = lower_bound(B + 1 , B + 1 + m , tmp) - B; if(pos <= m && B[pos] == tmp) { cout << "Alice" << '\n'; return ; } } for(int i = 0 ; i < 30 ; ++i) p[i] = 0; for(int i = 1 ; i <= n ; ++i) { tmp = A[i] ^ k; for(int j = 29 ; j >= 0 ; --j) { if(tmp & (1 << j)) { if(!p[j]) { p[j] = tmp; break; } else tmp ^= p[j]; } } } num = 0; for(int i = 0 ; i < 30 ; ++i) if(p[i]) num++; if((1 << num) == m) cout << "Bob" << '\n'; else cout << "Draw" << '\n'; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; cin >> T; while(T--) Solve(); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现