首先考虑最简单的情况,如果有一个数是 \(1\),那么第二步没有作用,胜负是固定的,先判掉。
然后发现题目给了一个很奇怪的条件:所有数的最大公约数为 \(1\),也就是至少有一个奇数,这提示我们从奇偶数下手。
发现第二步中的最大公约数的奇数因子是毫无意义的,因为无论是奇数还是偶数除以一个奇数,奇偶性都不变,没有改变第一步操作次数的奇偶性。
这给了先手一种必胜的思路,如果只进行第一步,先手必胜,先手又能保证两人每一次第二步中的最大公约数为奇数就必胜。
先手只需要每一次随便选一个偶数减 \(1\),由于初始至少有一个奇数,所以后手操作的时候至少有两个奇数,最大公约数一定为奇数,先手的操作最大公约数就更显然是奇数了。
这种情况的初始条件是只进行第一步先手必胜,也就是偶数个数为奇数。
如果只进行第一步先手必败呢?这时候先手肯定不能留给后手奇数,否则后手采用前面的方法必胜。所以先手只有一种选择,第一步删奇数。
如果初始奇数的个数大于 \(1\),那么先手删不完所有的奇数,后手必胜。
到现在,我们有三种判定了:
- 如果有 \(1\) 直接判定
- 如果有奇数个偶数先手必胜
- 如果有偶数个偶数并且有大于一个奇数后手必胜
如果恰好有偶数个偶数而且只有一个奇数,先手会删那个奇数,直接模拟这一次操作将奇数减 \(1\),这时所有的数都为偶数,最小公因数最小为 \(2\),最多进行 \(log\) 次就会变成上面三种情况的一种。
单次模拟时间复杂度为 \(O(nloga)\),总时间复杂度为 \(O(nlog^{2}a)\)。
#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int n;
int a[N];
int ji,ou,now=1,sum=0;
bool flag=false;void change(){for(int i=1;i<=n;i++){if(a[i]&1) a[i]--;}int gcd=a[1];for(int i=2;i<=n;i++) gcd=__gcd(gcd,a[i]);for(int i=1;i<=n;i++) a[i]/=gcd;
}int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n;for(int i=1;i<=n;i++){cin>>a[i];if(a[i]&1) ji++;else ou++;if(a[i]==1) flag=true;sum+=(a[i]-1);}if(flag){if(sum&1) cout<<"First";else cout<<"Second";return 0;}if(ou&1){cout<<"First";return 0;}else if(!(ou&1) && ji>1){cout<<"Second";return 0;}while(1){now=3-now;change();ji=ou=0;sum=0;for(int i=1;i<=n;i++){if(a[i]&1) ji++;else ou++;if(a[i]==1) flag=true;sum+=(a[i]-1);}if(flag){if(!(sum&1)) now=3-now;break;}if(ou&1){break;}else if(!(ou&1) && ji>1){now=3-now;break;}}if(now==1) cout<<"First";else cout<<"Second";return 0;
}