[CF1537D]Deleting Divisors

27 篇文章 0 订阅

题目

传送门 to CF

题目概要
一个博弈游戏,只有一个数字。两人轮流操作,每次可以将当前的数字 n 0 n_0 n0 减去它的因数 d    ( d ≠ 1 ∧ d ≠ n 0 ) d\;(d\ne 1\wedge d\ne n_0) d(d=1d=n0),不能操作者输。

问,最初数字是 n n n 时,先手是否有必胜策略。

数据范围与提示
1 0 4 10^4 104 组数据,每组数据 1 ≤ n ≤ 1 0 9 1\le n\le 10^9 1n109

思路

没有什么好的想法,干脆打了个表。震惊地发现,所有奇数都是先手必败!几乎所有偶数都是先手必胜!

为啥是几乎呢?因为我看到 n = 2 n=2 n=2 n = 8 n=8 n=8 是先手必败。于是我就这样交了一发,咋 W A \tt WA WA 了?

回来重新看了看表。啊咧咧!竟然 512 512 512 也是先手必败?再翻翻,怎么 32 32 32 也要出事儿?然后 128 128 128 也是反常情形?

好像 2 × 4 k 2\times 4^k 2×4k 都是先手必败诶!好,把这个结论补上去。 n n n 为奇数或者 n = 2 × 4 k n=2\times 4^k n=2×4k 先手必败,否则先手必胜。交一发,过了。

知道结论之后的证明,非常简单,归纳法即可,但是不容易直接想到。现在我们开始归纳法:

  • n n n 是奇数。若 n n n 为质数,直接输掉。否则,它的因子都是奇数,于是后继状态都是偶数。并且它的后继状态不是 2 k 2^k 2k,因为 n 0 − d n_0-d n0d 仍然是 d d d 的倍数,而 d d d 是一个奇因子。所以后继状态都是先手必胜。得证。
  • n ≠ 2 k n\ne 2^k n=2k 但是 n n n 为偶数。显然 n n n 不是质数,并且至少有一个奇因子。那么 n n n 减去这个奇因子,就得到了一个先手必败的后继。得证。
  • n = 2 k n=2^k n=2k 。若 k k k 为偶数,即 n = 4 k / 2 n=4^{k/2} n=4k/2,那么其存在后继状态 n 0 = 2 k − 1 n_0=2^{k-1} n0=2k1 是先手必败。若 k k k 为奇数,那么其后继 n 0 = 2 k − 1 n_0=2^{k-1} n0=2k1 和其他偶数都是先手必胜。得证。

世上只有打表好! O ( T log ⁡ n ) \mathcal O(T\log n) O(Tlogn) 没烦恼!

代码

#include <cstdio>
using namespace std;
inline int readint(){
	int a = 0; char c = getchar(), f = 1;
	for(; c<'0'||c>'9'; c=getchar())
		if(c == '-') f = -f;
	for(; '0'<=c&&c<='9'; c=getchar())
		a = (a<<3)+(a<<1)+(c^48);
	return a*f;
}

int logtwo(int x){
	for(int i=0; true; ++i)
		if((1<<i) >= x)
			return i;
	return -1;
}
int main(){
	for(int T=readint(); T; --T){
		int n = readint();
		if((n&-n) == n && (logtwo(n)&1))
			puts("Bob");
		else if(n&1) puts("Bob");
		else puts("Alice");
	}
	return 0;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值