CF1033G 题目传送门 \color{green} \text{CF1033G 题目传送门} CF1033G 题目传送门
题意
有 n n n 堆棋子,W 和 L 轮流取,W 每次只能取 a a a 个,L 每次只能取 b b b 个。
问,对于所有满足 a , b ∈ [ 1 , m ] a,b\in[1,m] a,b∈[1,m] 且 a , b ∈ Z a,b\in Z a,b∈Z 的 ( a , b ) (a,b) (a,b),假设 W 和 L 都绝对聪明,分别有几种方案满足如下四种情况。
- W win
- L win
- 先手 win
- 后手 win
题解
因为只有 W 真的是人win,所以答案是
0
,
m
2
,
0
,
0
0,m^2,0,0
0,m2,0,0。做完了。
对于 ( a , b ) (a,b) (a,b):
- W win: 拿 a a a 的必胜
- L win: 拿 b b b 的必胜
- 先手 win:谁先手谁胜
- 后手 win:谁后手谁胜
显然四种情况是不会有重叠的,容易发现 W win 和 L win 的情况是等价的。
那么其实只要考虑先手必胜和后手必胜的方案数,然后就能求出所有答案。
G
=
(
v
0
,
v
1
,
.
.
.
)
G=(v_0,v_1,...)
G=(v0,v1,...) 的局面等价于
G
=
(
v
0
m
o
d
(
a
+
b
)
,
v
1
m
o
d
(
a
+
b
)
,
.
.
.
)
G=(v_0 \mod(a + b),v_1 \mod(a+b),...)
G=(v0mod(a+b),v1mod(a+b),...) 的局面。好像可以解释成,分成了两个子游戏,因为这两个游戏的赢家先后手不变,所以其中有一个是
0
0
0 ,那么总的异或和不为
0
0
0。
那么我们的
v
i
v_i
vi 就会减小到
2
m
2m
2m 以内了。
草,叫起来太麻烦了……还是 A 每次拿
a
a
a
,B 每次拿
b
b
b 罢(。
我们现在只考虑先手胜还是后手胜的问题,所以我们不妨设 A 小,B 大(也就是 a ≤ b a \leq b a≤b)
-
情况1: v i ∈ [ 0 , a ) v_i \in [0,a) vi∈[0,a) 废点。不用管。
-
情况2: v i ∈ [ a , b ) v_i \in [a,b) vi∈[a,b) A 可拿 1 1 1 次,B 拿不了。
-
情况3: v i ∈ [ b , 2 a ) v_i \in [b,2a) vi∈[b,2a) A 可拿 1 1 1 次,B 拿 1 1 1 次。
-
情况4: v i ∈ [ m a x ( 2 a , b ) , a + b ) v_i \in[max(2a,b),a+b) vi∈[max(2a,b),a+b) A 可拿 2 2 2 次,B 拿 1 1 1 次。
我们注意到每堆最多被一个人拿。
分类讨论。被括起来的是必胜者。
- (A)存在情况 2。
- 不存在情况 2
(A)情况 4 4 4 个数 ≥ 2 \geq 2 ≥2:那么,第一轮里, A 肯定可以和 B 抢到一个情况 4,将它转化为情况 2。
情况 4 个数 = 1 =1 =1
情况 3 和情况 4 个数( ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b] )为奇数。
(A)A 是先手
(B)B 是先手
(A)情况 3 和情况 4 个数 ( ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b]) 为偶数。
不存在情况 4。
情况 3 个数 ( ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b]) 是奇数
(A)A 是先手
(B)B 是先手
情况 3 个数 ( ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b]) 是偶数
(B)A 是先手
(A)B 是先手
整合一下。只要考虑先手必胜和后手必胜的 ( a , b ) (a,b) (a,b)。
- 不存在情况 2
情况 4 个数 = 1 =1 =1。
(先) ∑ [ v i ≥ b ] \sum[v_i \geq b] ∑[vi≥b] 为奇数
不存在情况 4。
(先):情况 3 个数 ( ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b]) 是奇数
(后):情况 3 个数 ( ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b]) 是偶数
那么我们就可以暴力枚举 O ( n m 2 ) O(nm^2) O(nm2) 了。
然鹅
过不去。。。
考虑先手胜利的情况:
- 不存在 v i ∈ [ a , b ) v_i \in[a,b) vi∈[a,b)
-
∑
[
v
i
∈
[
max
(
2
a
,
b
)
,
a
+
b
)
]
≤
1
\sum [v_i \in [\max(2a,b),a+b)]\leq 1
∑[vi∈[max(2a,b),a+b)]≤1
并且 ∑ [ v i ≥ b ] \sum[v_i \geq b] ∑[vi≥b] 为奇数。
考虑后手胜利的情况:
- 不存在 v i ∈ [ a , b ) v_i \in[a,b) vi∈[a,b)
- ∑ [ v i ∈ [ max ( 2 a , b ) , a + b ) ] = 0 \sum[v_i \in [\max(2a,b),a+b)]=0 ∑[vi∈[max(2a,b),a+b)]=0 并且 [ v i ≥ b ] [v_i \geq b] [vi≥b] 为偶数。
首先枚举 a + b a+b a+b
对 v v v 进行排序。
要求 a , b a,b a,b 就处于一个 ( v j , v j + 1 ] (v_j,v_j+1] (vj,vj+1] 的区间内。枚举是哪个区间。(边界区间也要考虑)
然后 ∑ [ v i ≥ b ] \sum [v_i \geq b] ∑[vi≥b] 的奇偶性就可知了。分别考虑先手胜和后手胜的情况。
设最大的 v v v 是 v n v_n vn,次大的是 v n − 1 v_{n-1} vn−1。
1. 先手
-
∑ [ v i ∈ [ max ( 2 a , b ) , a + b ) ] ≤ 1 \sum[v_i \in[\max(2a,b),a+b)]\leq 1 ∑[vi∈[max(2a,b),a+b)]≤1
-
即: max ( 2 a , b ) > v n − 1 \max(2a,b)>v_{n-1} max(2a,b)>vn−1
-
即:必须满足 a > n v − 1 2 a> \tfrac{n_v-1}{2} a>2nv−1
和 b > v n − 1 b>v_{n-1} b>vn−1 中至少一个。 -
看起来这个玩意儿需要容斥。但是实际上不用。
-
因为 a , b a,b a,b 在一个区间里,所以 b > v n − 1 b>v_{n-1} b>vn−1 的时候 a a a 一定 大于 v n − 1 > n v − 1 2 v_{n-1}>\tfrac{n_v-1}{2} vn−1>2nv−1。所以只需要计算 a > n v − 1 2 a>\tfrac{n_v-1}{2} a>2nv−1 的情况。
2. 后手
-
∑ [ v i ∈ [ max ( 2 a , b ) , a + b ) ] = 0 \sum [v_i \in [\max(2a,b),a+b)]=0 ∑[vi∈[max(2a,b),a+b)]=0
-
即: max ( 2 a , b ) > v n \max(2a,b)>v_n max(2a,b)>vn
-
即: a > n v 2 a>\tfrac{n_v}{2} a>2nv或 b > v n b>v_n b>vn 同理。
-
因为 a , b a,b a,b 在一个区间里,所以 b > v n b>v_n b>vn 的时候 a a a 一定大于 v n > n v − 1 2 v_n>\tfrac{n_v-1}{2} vn>2nv−1。所以只需要计算 a > n v 2 a>\tfrac{n_v}{2} a>2nv 的情况。
那么我们最后会框出一个 a a a 的范围 [ l , r ] [l,r] [l,r],然后 b ∈ ( v j , v j + 1 m o d s ) b \in (v_j,v_{j+1}\mod s) b∈(vj,vj+1mods)
l=max(v[j]%s,mx/2)+1,r=min(v[j+1]%s,m);
注意到我们开始有个设定叫 a ≤ b a \leq b a≤b,现在我们想抛弃它,否则会很难写。
那么就是
min
(
a
,
b
)
∈
[
l
,
r
]
,
max
(
a
,
b
)
∈
∈
(
v
j
,
v
j
+
1
m
o
d
s
)
\min (a,b) \in [l,r],\max(a,b)\in \in (v_j,v_{j+1} \mod s)
min(a,b)∈[l,r],max(a,b)∈∈(vj,vj+1mods)
也就是 min ( a , b ) ≥ l , max ( a , b ) ≤ r \min(a,b) \geq l,\max(a,b) \leq r min(a,b)≥l,max(a,b)≤r
a ≥ l , b ≥ l , a ≤ r , b ≤ r a \geq l,b \geq l,a \leq r,b \leq r a≥l,b≥l,a≤r,b≤r
那么最终 a a a 的范围就是 [ min ( l , s − r ) , max ( r , s − l ) ] [\min (l,s-r),\max (r,s-l)] [min(l,s−r),max(r,s−l)]
AC Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define ls(x)((x)<<1)
#define rs(x)((x)<<1|1)
#define fi first
#define se second
#define mkp make_pair
#define PII pair<int,int>
const int N=110,M=2e5+10;
int n,m,tmp[N];
ll v[N],ans,ansf,anss;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%lld",&v[i]);
for(int s=2;s<=(m<<1);s++)
{
tmp[0]=0;tmp[n+1]=s-1;
for(int i=1;i<=n;i++)
tmp[i]=v[i]%s;
sort(tmp,tmp+(n+1)+1);
for(int i=1;i<=n+1;i++)
{
//a,b在 [tmp[i-1],tmp[i]]之间。
//fl: >=b 的个数是否为奇数。
bool fl=(n+1-i)&1;
int l=max(tmp[i-1],tmp[n-1+(!fl)]/2)+1,r=min(tmp[i],m);
//是奇数:可能后手必败(先手必胜)。找次大
//是偶数:可能先手必败(后手必胜)。找最大
(fl?ansf:anss)+=max(0,min(r,s-l)-max(l,s-r)+1);
}
}
ans = (1ll*m*m-ansf-anss)>>1;
printf("%lld %lld %lld %lld\n",ans,ans,ansf,anss);
return 0;
}
啊啊啊,一晚上的时间都耗在此题上了,中间上了厕所回来发现有个小可爱把我题解删了,亏了可以Ctrl+Z
,不然我会气吐血的……
最后感谢老师细心地解答/纠正一些离大谱的问题/bx