Codeforces Round #581 (Div. 2)
目录
Contest Info
[Practice Link](https://codeforc.es/contest/1204)
Solved | A | B | C | D1 | D2 | E |
---|---|---|---|---|---|---|
6/6 | O | O | O | O | Ø | Ø |
- O 在比赛中通过
- Ø 赛后通过
- ! 尝试了但是失败了
- - 没有尝试
Solutions
A. BowWow and the Timetable
题意:
找一个二进制表示的数\(n\)中有多少个小于\(n\)的\(4\)的幂次的数。
思路:
计算\(\left\lceil log_4s \right\rceil\)。
B. Mislove Has Lost an Array
签到。
C. Anna, Svyatoslav and Maps
题意:
给出一张图的邻接矩阵,然后给出一条路径,要缩短路径,使得缩短后的路径的任意两点之间加上这两点的最短距离经过的点,会变成原路径。
思路:
跑一下\(Floyd\),然后用栈判断,栈顶的三个点的那么中间点能否移去。
D1. Kirk and a Binary String (easy version)
题意:
给出一个\(01\)串,问构造另一个\(01\)串,使得两个\(01\)串的任何一个子段的\(LIS\)长度相同,并且要保证\(0\)的个数尽量多。
\(|s| \leq 2000\)
思路:
猜测\(0\)的个数最多的方案下只有第一个串那个位置是\(1\)的话,构造的那个串的那个位置才需要放\(1\)。
然后每次暴力判断一下,如果不合法,那一位就放\(1\)
D2. Kirk and a Binary String (hard version)
题意:同\(D1\),\(|s| \leq 10^5\)
思路:
我们考虑倒着做:
- \(dp0\)表示以\(0\)开头的\(LIS\)的最大长度
- \(dp1\)表示一\(1\)开头的\(LIS\)的最大长度
- 我们发现左边如果增加一位\(0\),那么\(dp0 = max(dp0, dp1) + 1\)
- 否则如果增加一位\(1\),那么\(dp1 = dp1 + 1\),并且\(dp0\)不变
- 那么我们注意到,如果原串的那一位是\(0\),那么直接放\(0\)没有什么问题。
- 当原串那一位是\(1\)的时候,我们如果在新串中放\(0\)可能导致新串中的\(max(dp0, dp1)\)产生变化
- 也就是说当\(dp0 < dp1\)的时候,那么这一位如果放\(0\)放\(1\),那么会使得\(dp0 = dp1 + 1\),如果放\(1\),会使得\(dp1 + 1\),发现\(max(dp0, dp1)\)没有变
- 而每次左边增加一个数,只增加了以它开头的一些子段,而\(max(dp0, dp1)\)就是保证了这些子段的\(LIS\)的最大长度。
E. Natasha, Sasha and the Prefix Sums
题意:
有\(n\)个\(1\),\(m\)个\(-1\),每出每一种方案的最大前缀和的和。
思路:
- 考虑枚举每一个最大前缀和\(a\),然后统计有多少种序列的方案的最大前缀和是\(a\)。
- 考虑\(n \leq m\)的情况:
- 在二维平面上,从\((0, 0\)开始,我们令放一个\(1\)为向右走一步,放一个\(-1\)为向上走一步,那么我们要知道最大前缀和\(\leq a\)的方案数就是所有路径不跨过\(y = x - a\)的方案数
- 然后稍微容斥一下,即可求得最大前缀和恰好为\(a\)的方案数。
- \(n > m\)的情况转化成\(m \leq n\)的情况即可