[atARC105D]Let's Play Nim
先对$n$分奇偶两种情况考虑——
$n$为奇数,显然先手希望最终产生的$x_{1}\oplus x_{2}\oplus...\oplus x_{n}=0$
对于后手,考虑构造:将最大的未被选择的$a_{k}$放在最大的$x_{t}$上,很明显除去先手的第一个以外,后手的每一次都比先手的下一次放的数大
设$a_{k}$为先手第一个取的位置,即必然有$x_{t}-a_{k}\ge \sum_{i=1}^{n}a_{i}-a_{k}-x_{t}$,即$x_{t}>\sum_{i=1}^{n}a_{i}-x_{t}$
而$x_{1}\oplus x_{2}\oplus...\oplus x_{n}=0$当且仅当$x_{t}=x_{1}\oplus x_{2}\oplus...x_{t-1}\oplus x_{t+1}...\oplus x_{n}\le \sum_{i=1}^{n}a_{i}-x_{t}<x_{t}$,因此后手必胜
$n$为偶数,显然先手希望最终产生的$x_{1}\oplus x_{2}\oplus...\oplus x_{n}>0$
对于先手,类似上述后手的构造,那么有$x_{t}\ge \sum_{i=1}^{n}a_{i}-x_{t}$
最终异或能为0的必要条件是$x_{t}=\sum_{i=1}^{n}a_{i}-x_{t}$,同时在这样的情况下,必然是$a_{i}$成对出现,后手可以模仿先手的操作使得异或为0,因此此时后手必胜
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<bits/stdc++.h> 2 using namespace std; 3 map<int,int>mat; 4 int t,n,a[100005]; 5 int main(){ 6 scanf("%d",&t); 7 while (t--){ 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 10 if (n&1)printf("Second\n"); 11 else{ 12 mat.clear(); 13 int flag=0; 14 for(int i=1;i<=n;i++){ 15 mat[a[i]]^=1; 16 flag+=2*mat[a[i]]-1; 17 } 18 if (flag)printf("First\n"); 19 else printf("Second\n"); 20 } 21 } 22 }