题目:给定长度为n的数组a,A和B轮流拿走一个数,开始时A和B拥有的v为0,A和B每次拿走一个数时,他的v = v^ ai,A和B都很聪明,问都按照最优的情况考虑,拿完所有数之后A和B的v的大小。
思路:我们可以想到二进制的高低位性质,所以一个人如果有一个最高位二进制为1而另外一个人是0,则前者一定赢。我们可以把所有数的二进制位取下来,我们知如果该二进制位为偶数,说明这个位一定可以变成0;否则如果为奇数,则一定会出现一个人是1,另一个是0的情况。根据枚举一些样例,可以总结出以下的规律:
(前提:该bit为奇数)
① cnt[bit] % 4 == 1 则前者一定赢,只要前者把这个1拿走
② cnt[bit] % 4 == 3 (*) 如果 (n - cnt[bit])% 2 == 0(&),则后者赢,因为后者一定可以让前者取到(*)多出的1,反之如果为1,则前者把(&)1拿走,让后者拿(*)多出的1
1 #include<iostream> 2 #include<string> 3 #include<vector> 4 #include<cstdio> 5 6 #define ll long long 7 #define pb push_back 8 9 using namespace std; 10 11 const int N = 1e5; 12 int bit[N]; 13 14 void solve() 15 { 16 int T; 17 cin >> T; 18 while(T--){ 19 int n; 20 cin >> n; 21 22 for(int i = 0; i <= 40; ++i) bit[i] = 0; 23 24 for(int i = 1; i <= n; ++i){ 25 int x, b; 26 cin >> x; 27 b = 0; 28 while(1){ 29 if(!x) break; 30 bit[b++] += (x & 1); 31 x >>= 1; 32 } 33 } 34 35 int inx = -1; 36 for(int i = 40; i >= 0; --i){ 37 if(bit[i] % 2 == 0) continue; 38 inx = i; 39 break; 40 } 41 42 if(inx == -1){ 43 cout << "DRAW" << endl; 44 continue; 45 } 46 47 int a = bit[inx] % 4; 48 int b = (n - a) % 2; 49 50 if(a == 3 && b == 0) cout << "LOSE" << endl; 51 else cout << "WIN" << endl; 52 } 53 54 } 55 56 int main() { 57 58 ios::sync_with_stdio(false); 59 cin.tie(0); 60 cout.tie(0); 61 solve(); 62 //cout << "ok" << endl; 63 return 0; 64 }