Codeforces Round #668 (Div. 2)/Codeforces1405 题解(A-E)

AC代码

A. Permutation Forgery

逆序输出排列(p)即可。

B. Array Cancellation

依据题意,若(a_i)大于(0),那么(a_i)可以免费地用在增加后续值为负的元素。

从前往后遍历数组(a),用一个计数器记录可免费用的正数和,每遇到一个正的(a_i)就加到计数器上;遇到负的(a_i)时就尽可能地用花费免费可用的正数去增加这个(a_i)

这样遍历完一遍之后,数组中的元素就都只能花钱去操作了,求正元素的和或者求负元素的和后取相反数都可以。

C. Balanced Bitstring

通过观察可以发现:满足条件的01串必定以(k)为周期。

然后就只需要判断(s)是否可能以(k)为周期,以及(s[0...k-1])是否可能满足条件。

D. Tree Tag

实际上就是若Alice和Bob之间的距离小于等于(da),那么Alice就赢了。

感觉sample2就是在暗示讨论一条链,在最好的情况下也就是树的直径就可以。

首先,Bob最优的操作就是先躲到直径的一端,然后等者Alice靠近时再借机跳走。

然后,在最差的情况下,Alice和Bob之间的距离为(da+1),也就是若Alice再靠近Bob一步且Bob不操作,Bob就输了。这个时候,若Alice不靠近,Bob就不需要操作;若Alice靠近,Bob就需要跳到离Alice新位置的距离大于(da)的位置。Alice用最优操作的情况下,Bob的移动距离要大于(2da+1)

然后就可以得出结论:当且仅当Alice和Bob的初始距离大于(da),且(db)和树的直径都大于等于(2da + 1)时,Bob胜,反之Alice胜。

E. Fixed Point Removal

首先,用(i-a_i)替换(a_i),这样,题目中允许的操作就变为删除一个零,然后将后面的所有元素都减一。

然后,先读进来所有的询问,然后离线地回答询问。

(f(l, r))为仅考虑子数组(a[l...r])时,最多能删除多少个元素。

通过观察可以得到:若(i < j),则(f(i,r) ge f(j, r))。因为对于(a[i...r])而言,最差也就是只使用(a[j...r])的元素,所以对于固定的(r)(f(i,r))随着(i)的增加不减。

从小到大枚举右端点(r),现在(r)就可以视为常数。用一个数组(s)记录右端点为(r)时,各个左端点的答案,即(s_i = f(i, r))

(a_r < 0),那么无论怎样这个元素都无法被删除;反之,对于任意一个左端点(l),如果(f(l,r) ge a_r),那么对于这个区间而言,就可以先删除(a_r)个元素,然后再删除(a_r),再执行剩下的操作,即删除(a_r)并不会影响前面的操作。所以,若(f(l,r) ge a_r),则(f(l,r)=f(l,r-1)+1)。结合之前的结论,若找到了满足条件的最大的(l),那么可以用一个区间加法操作更新所有需要更新的(s_i)

到这里,这题的做法就比较明显了,枚举右端点,看是否可以用当前点扩展答案,若能扩展就是一个区间加法;然后回答所有右端点为当前端点的询问,也就是一个单点取值。这两个操作是树状数组或者线段树的基本操作,不再赘述。

总结

17min过了前3题,看了下排名是26,然后就开始自闭了

看到D题题面人傻了,本来博弈论就不太熟悉,还给整了个树上博弈,所以不太有信心做出来。仔细看了之后发现结论还是比较好推的,就是犯了低级错误疯狂WA on test2。

原文地址:https://www.cnblogs.com/zengzk/p/13624522.html