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。

posted @ 2020-09-07 00:41  _Backl1ght  阅读(335)  评论(0编辑  收藏  举报