题目背景
小 Y 和小 Z 是一对好朋友,他们在玩一个游戏。游戏只有一个回合。
题目描述
有一个牌堆,一共有 n n n 张牌,第 i i i 张牌上有一个数 a i a_i ai,其中第一张牌是堆顶。
小 Z 先取牌,他可以从堆顶开始取连续若干张牌(可以取 0 0 0 张),取完的牌拿在手上,也就是不在牌堆里了。
然后小 Y 取牌,同样,她也可以从堆顶开始取连续若干张牌(可以取 0 0 0 张)。
如果一个人手上的牌的数字和大于 X X X,那么他的分数就是 0 0 0,否则分数就是数字和。
分数高的人获胜,如果一样高,则无人获胜。
小 Z 为了获胜,使用了透视挂,即他知道牌堆里每张牌上写的数。
现在问你对于满足 1 ≤ X ≤ K 1 \leq X \leq K 1≤X≤K 的所有整数 X X X,哪些可以使得小 Z 有必胜策略,即小 Z 取完后,不管小 Y 怎么取都一定会输。
输入格式
第一行一个整数 n n n,表示牌堆里有几张牌。
第二行 n n n 个整数 a 1 … n a_{1\dots n} a1…n表示每张牌上写的数。
第三行一个正整数 K K K,含义见题目描述。
输出格式
第一行一个整数,表示满足要求的 X X X 的个数。
第二行从小到大依次输出满足要求的 X X X,用空格隔开。
输入输出样例
输入 #1
5
1 4 3 2 2
5
输出 #1
3
1 2 3
说明/提示
【样例解释】
X = 1 , 2 , 3 X=1,2,3 X=1,2,3 时,小 Z 取一张牌,小 Y 不管怎么取都是零分。
X = 4 X=4 X=4 时,小 Z 如果取 1 1 1 张,那么小 Y 取 1 1 1 张小 Y 就赢了;否则小 Z 只能是零分。
X = 5 X=5 X=5 时,小 Z 如果取 1 1 1 张,那么小 Y 取 11 张小 Y 就赢了;小 Z 如果取了 2 2 2 张,小 Y 也取 2 2 2 张,平局;否则小 Z 只能是零分。
【数据范围】
对于 100 % 100\% 100% 的数据, 1 ≤ n , K ≤ 1 0 6 1\leq n,K \leq 10^6 1≤n,K≤106, 1 ≤ a i ≤ K 1\leq a_i \leq K 1≤ai≤K。
题解
思维题,挺有意思的。
这题很坑,我花了半个小时想思路,导致没写最后一题(虽然我大概率写不出来)
看数据范围大概率复杂度是 O ( n ) O(n) O(n)的,应该要利用单调性
发现游戏只进行一轮,也就是说只需要选取两个点——p和q,使得 s u m [ p ] > s u m [ q ] − s u m [ p ] sum[p]>sum[q]-sum[p] sum[p]>sum[q]−sum[p],也就是 2 × s u m [ p ] > s u m [ q ] 2\times sum[p]>sum[q] 2×sum[p]>sum[q]。
不妨从反方向思考,如果小Z有可能会输,那么需要满足什么条件。首先
s
u
m
[
q
]
≤
x
+
s
u
m
[
p
]
sum[q]\le x+sum[p]
sum[q]≤x+sum[p],然后
2
×
s
u
m
[
p
]
≤
s
u
m
[
q
]
2\times sum[p] \le sum[q]
2×sum[p]≤sum[q],联立得:
2
×
s
u
m
[
p
]
≤
s
u
m
[
q
]
≤
x
+
s
u
m
[
p
]
2\times sum[p] \le sum[q]\le x+sum[p]
2×sum[p]≤sum[q]≤x+sum[p]
不难发现,在x固定的情况下,
s
u
m
[
p
]
sum[p]
sum[p]越小这个范围越大,越可能找到合适的
s
u
m
[
q
]
sum[q]
sum[q];在p固定的情况下,
x
x
x越大这个范围越大,越可能找到合适的
s
u
m
[
q
]
sum[q]
sum[q]。
所以最后处理答案时,就让x从大往小扫,同时找q,如果找不到就减小p,直到找到q为止,这其实就是用双指针。
如上是我的想法,但是好多luogu的大佬们都是先预处理p固定时q的最小值,然后再用x从大往小扫的,这样貌似思路更简单。
收获:
- 单调性的灵活运用(正好最近在出类似的题)