2023牛客多校9-G-Non-Puzzle: Game
题意:给出N个数,Alice先手,每轮可以加入任意两个数异或的结果,先得出K者获胜,若为无限轮则为平手
思路:情况可以分为三种:Alice一步胜,Alice取后Bob必胜,平局。
对于第一种情况,只需要在原数组中查询有无ai异或k的存在即可,数据范围允许用set。
对于第二种情况,需要满足数组中总存在ap使任意 ai异或aj=ap异或k。对此,可以利用线性基的封闭性,将ai异或k加入线性基,如果线性基可以表示的数的个数恰好为N,则条件成立,Bob总能取胜。
对于第三种情况则是第二种情况不成立时,双方都可以利用异或的性质,使得自己的操作无意义,总而达成平局
'''
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+3;
int w[N];
int st[35];
int t,n,m,cnt;
inline void print(int x){
cout<<((x==-1)?"Draw\n":(x?"Alice\n":"Bob\n"));
}
inline void add(int x){
for(int i=30;i>=0;i--)
if(x&(1<<i)){
if(!st[i]){
st[i]=x;
cnt++;
}
x^=st[i];
}
}
inline bool find(int x){
for(int i=30;i>=0;i--)
if(x&(1<<i)){
if(!st[i]) break;
x^=st[i];
}
return x>0;
}
inline void solve(){
memset(st,0,sizeof st);
cnt=0;
cin>>n>>m;
set<int>s;
for(int i=1;i<=n;i++){
cin>>w[i];
s.emplace(w[i]);
}
for(int i=1;i<=n;i++)
if(s.find(w[i]^m)!=s.end())
return print(1);
for(int i=1;i<=n;i++) w[i]^=m;
sort(w+1,w+1+n);
n=unique(w+1,w+1+n)-w-1;
for(int i=1;i<=n;i++) add(w[i]);
if((1<<cnt)==n) return print(0);
return print(-1);
}
int main(){
cin>>t;
while(t--) solve();
// system("pause");
}
'''