AtCoder 137 C Distinct Numbers
题意
给定一个长度为 n ( 2 ≤ n ≤ 3 × 1 0 5 ) n\left(2\le n\leq3\times 10^{5}\right) n(2≤n≤3×105)的严格递增的自然数序列 A 1 , A 2 , ⋯ , A n A_1,A_2,\cdots,A_n A1,A2,⋯,An
- 现在有两个人在轮流进行如下操作:
- 选择序列中最大数 m x mx mx,使其变成一个小于 m x mx mx的自然数,并且变化后需要满足:序列中没有相同的数。
- 然后将由另一个人来对这个序列进行操作。
- 直至一个人无法操作的时候,则其被判负
思路
做这类博弈题的时候,我一般把自己带入,当作是自己是先手的那个人
- 首先,做博弈题的第一步就是搞清楚:当你面对什么局面的时候,代表被判负了
- 被判负,即比最大数
m
x
mx
mx小的所有的自然数都存在了,故这是一个连续的、字典序最小的序列
- 此处序列的字典序指的是一个数代表一个字符
- 且因为前面的操作都是合法的,所以它们都是不同的
- 故被判负的终态为 0 , 1 , 2 , ⋯ , n − 1 0,1,2,\cdots,n-1 0,1,2,⋯,n−1
- 被判负,即比最大数
m
x
mx
mx小的所有的自然数都存在了,故这是一个连续的、字典序最小的序列
- 考虑什么情况会到达终态(被判负),即被判负倒推一步
- 我们用移动石子、石字占领位置的模型,来替换掉一个数变成某个数的思想
- 我们用
all
表示 0 0 0到 n − 1 n-1 n−1的所有位置- 局面1:假设
all
中有 1 1 1个空位,且位置 n n n已经被占领了。那么我们直接将其移动到all
那个空位,对手面对终态,即表示我们:判胜 - 局面2:假设
all
中有 2 2 2个空位,且位置 n n n和位置 n + 1 n+1 n+1已经被占领了。那么我们第一步只能被迫将 n + 1 n+1 n+1移动到一个空位,然后对手面对上面的局面1,即表示对手胜利,也就表示我们的结果为:判负 - 局面3:假设
all
中有 3 3 3个空位,且位置 n n n和位置 n + 1 n+1 n+1、位置 n + 2 n+2 n+2已经被占领了。那么我们第一步只能被迫将 n + 2 n+2 n+2移动到一个空位,然后对手面对局面2,即表示对手失败,也就表示我们的结果为:判胜 - 以此类推,此类
all
中存在空位,剩余的石子从位置 n n n开始的连续的情况
- 局面1:假设
然后我们开始就讲正解思路,分类讨论以下两种类型
类型一
若 A [ n ] > A [ n − 1 ] + 1 A[n]>A[n-1]+1 A[n]>A[n−1]+1,我们分以下两种情况考虑
- 如果存在一个方案,让 A [ n ] A[n] A[n]变为某一个比 A [ n − 1 ] A[n-1] A[n−1]小的数,使其的后继状态全是必败态( N N N态),那么我们就转移到这个状态,对手必败,等价我们必胜
- 如果不存在上述这样的一个方案,说明面对上述方案转移到的局面是一个必胜态,那么我们也要想办法让自己面对这样一个必胜态,我们就让对手强制把我们送到这个必胜态,我们让 A [ n ] A[n] A[n]变为 A [ n − 1 ] + 1 A[n-1]+1 A[n−1]+1即可。这样对手就会被迫执行上述方案的操作,我们依旧必胜
- 故综上,当 A [ n ] > A [ n − 1 ] + 1 A[n]>A[n-1]+1 A[n]>A[n−1]+1时,是先手必胜的
类型二
若 A [ n ] = A [ n − 1 ] + 1 A[n]=A[n-1]+1 A[n]=A[n−1]+1
此处我先说结论,后证明
- 当 A [ n ] − ( n − 1 ) A[n]-(n-1) A[n]−(n−1)为奇数时,必胜
- 当 A [ n ] − ( n − 1 ) A[n]-(n-1) A[n]−(n−1)为偶数时,必败
以下简称 A [ n ] − ( n − 1 ) A[n]-(n-1) A[n]−(n−1)为距离
我先举一个局面,大家体会一下,
n
=
6
n=6
n=6,初始局面
0
,
2
,
3
,
5
,
99
,
100
0,2,3,5,99,100
0,2,3,5,99,100,按照我最上面说的all
中有两个空位置,需要考虑的只有99 100
,根据上述的结论,距离为100 - 5 = 95
是奇数,为必胜态
下面我称我们为A
,对手为B
A
面对的初始局面为99 100
操作后为98 99
B
此时面对的局面为98 99
,距离为99 - 5 = 94
是偶数,结论中为必败态,假设B
有两种操作
- 操作后为
45 98
,我们操作后为44 45
- 操作后为
46 98
,我们操作后为46 47
我们无论如何始终都可以让B
面对最大的数是奇数的局面(必败态,因为例子中n-1
为奇数),直到最后一个最大的奇数5
但是怎么为什么这结论就是正确的呢?
博弈论有以下基本性质
- 必败态的所有后继状态都是必胜态
- 必胜态的后继状态中至少有一个是必败态
回到我们刚刚说的all
的那几种局面,局面1
中距离为奇数(必胜),局面2
中距离为偶数(必败),局面3
中距离为奇数(必胜)
我们可以从局面2
中拓展,假设最后两个石子的状态不为n n+1
- 若为
n+1 n+2
,则我们移动到n n+1
,对手必败,我们必胜 - 若为
n+2 n+3
,若我们移动到n+1 n+2
,面对这个局面的对手必胜,我们必败;若我们移动到n n+2
,对手可以移动到n n+1
我们必败;若我们将n+2
移动到all
中的一个空位置,对手只需再移动一步,我们就面对终态。故面对该状态时我们必败 - 于是我们便可以数学归纳法,
all
只有两个空位的时候且最后两个石子连续的情况,距离为奇数必胜,为偶数必败
此时我们还有一个问题没解决,如果all
中不止两个空位且最后两个石子连续的情况——即一般情况(因为一个空位的情况我们已经讨论完毕了,即必胜)
结合从局面2
的拓展和上述枚举的局面99 100
中过程的思想,我们便可证明结论的正确性,相信此时大家已经懂得差不多了,此处我就不在赘述了
代码
最后附上本菜狗的代码
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
int main()
{
int n, x, y;
cin >> n;
rep(i, 3, n)
cin >> x;
cin >> x >> y;
bool win = (y > x + 1) | ((y - (n - 1)) & 1);
cout << (win ? "Alice" : "Bob") << '\n';
}