problem
Luogu链接
solution
case1
:aaa 中如果有 111 的存在,那么相当于第二步失效,最后的结果仅由 ∑ai−1\sum a_i-1∑ai−1 的奇偶性决定(奇数先手赢,偶数后手赢)
奇数先手赢,偶数后手赢。
case2
:如果 ∑ai−1\sum a_i-1∑ai−1 为奇数,先手必胜。
这看起来就似乎是正确的。
首先因为偶数除以奇数还是偶数,奇数除以奇数还是奇数,所以如果 gcd\gcdgcd 是奇数,对奇偶性不影响。
如果先手能维持这个奇偶性到最后,即保证每人每次只有第一步操作有效,那他就赢了。
先手只需任选一个偶数 −1-1−1,再算上初始局面必然包含的一个奇数(否则初始 gcd\gcdgcd 不为 111),这样至少就有两个奇数。
- 此时若序列长度 >2>2>2,先手 −1-1−1 之后:
- gcd=1\gcd=1gcd=1。后手再让任意一个数 −1-1−1,序列的 gcd\gcdgcd 仍然为 111,后手的第二步等价于无效。
- gcd≠1\gcd\ne 1gcd=1,但 gcd\gcdgcd 也一定是奇数。除掉 gcd\gcdgcd 后,出现 111,奇偶性未改变。后手仍然面临的奇偶性为偶。先手必胜。
- 特殊情况是序列长度 =2=2=2,先手 −1-1−1 之后:
- 可能两数相等,那正好就直接赢了。
- 要是不相等,并且 −1-1−1 之后出现了倍数关系,那没什么影响,显然一个是另一个的奇数倍。约去 gcd\gcdgcd 后就是一个 111 加上一个奇数,后手面临的奇偶性仍然为偶,先手仍然获胜。
要想保证每人每次只能取一个也很简单,先手只需任选一个偶数减1,再算上初始局面必然包含的一个奇数(否则初始gcd不为1),这样就至少有两个奇数了。
case3
:如果 ∑i=1nai−1\sum_{i=1}^na_i-1∑i=1nai−1 为偶数,且有 >1>1>1 个 aia_iai 为奇数,则先手必败。
若有多个奇数,这一轮先手选择一个变为偶数,gcd\gcdgcd 仍然只可能是奇数,下一轮后手就能将其重新变回偶数,使先手第二步无效。
case4
:如果为偶数,先手肯定想要翻盘,唯一办法是 2∣gcd2\mid \gcd2∣gcd。
如果 ∑i=1nai−1\sum_{i=1}^na_i-1∑i=1nai−1 为偶数,且只有一个奇数,先手一定操作这个奇数,那么这一轮至少能 /2/2/2,这是唯一的翻盘机会。
考虑做完上述特判和操作后,将操作权递交给对手。
只有 case4
是需要模拟操作下去的 O(nlog2w)O(n\log^2w)O(nlog2w),其余三种情况一步判断输赢即可。
#include <bits/stdc++.h>
using namespace std;
#define maxn 100005
#define int long long
int n;
int a[maxn];int gcd( int x, int y ) {if( ! y ) return x;else return gcd( y, x % y );
}signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) scanf( "%lld", &a[i] );bool op = 0;while( 1 ) {int cnt = 0, sum = 0, flag = 0;for( int i = 1;i <= n;i ++ )cnt += (a[i] & 1), sum += a[i] - 1, flag |= (a[i] == 1);if( sum & 1 ) break;if( cnt ^ 1 ) { op ^= 1; break; }if( flag ) { op ^= 1; break; }int d = 0;for( int i = 1;i <= n;i ++ ) {if( a[i] & 1 ) a[i] --;d = gcd( d, a[i] );}for( int i = 1;i <= n;i ++ ) a[i] /= d;op ^= 1;}if( ! op ) puts("First");else puts("Second");return 0;
}