题解:P11010 『STA - R7』Divide and Merge Game

· · 题解

考虑到如果有任意一个数是 $> \frac{n}{m}$ 的,那 Bob 无论如何也无法取到 $= \frac{n}{m}$ 的集合。 为了尽量构造出 $> \frac{n}{m}$ 的数,Alice 会选择填 $k-1$ 个 $1$,以及剩下的她期望 $> \frac{n}{m}$ 的数。 于是得,在 $n - (k - 1) > \frac{n}{m}$ 时,Alice 一定能赢。(这里显然 $m$ 默认取 $n$ 的最小真因子) 然后考虑如果 Alice 无法做到上面那种情况,那就是说所有数都会 $\leq \frac{n}{m}$,怎么办。 考虑设当前最大数为 $x$,自然不会有其他数 $> 1$。因为如果有非 $1$ 的数那为什么不加在 $x$ 身上呢(以利于卡死 Bob)? 但是经过之前的分析发现,只要 Bob 取到最小的 $m$,我们就卡不死。 于是得,在 $n - (k - 1) \leq \frac{n}{m}$ 时,Bob 一定能赢。(这里 $m$ 取值同上) 于是预处理一下 $10^5$ 以内的质数,每次找一下最小的能整除的就可以。 简单想一下应该比 $O(T\sqrt{n})$ 小很多,于是就能过了。 ```cpp #include<bits/stdc++.h> using namespace std; int prime[100010] , tot; bool flag[100000010]; void solve() { int n , k; scanf("%d%d" , &n , &k); bool qwq = 0; for(int i = 1 ; prime[i] * prime[i] <= n ; i ++) { if(n % prime[i] == 0) { int x = n / prime[i]; if(n - (k - 1) > x) printf("Alice\n"); else printf("Bob\n"); qwq = 1; break; } } if(!qwq) printf(n == k ? "Bob\n" : "Alice\n"); // 一个细节,n=k 时应当 Bob 赢,因为是全 1。 } int main() { for(int i = 2 ; i <= 100000 ; i ++) { if(!flag[i]) prime[++ tot] = i; for(int j = 1 ; j <= tot ; j ++) { int nxt = i * prime[j]; if(nxt > 100000) break; flag[nxt] = 1; if(i % prime[j] == 0) break; } } int T; scanf("%d" , &T); while(T --) solve(); return 0; } ```