Educational Codeforces Round 101 (Rated for Div. 2) (A-F)

AC代码

A. Regular Bracket Sequence

注意到题目保证只有一个左括号和一个右括号。

所以只有字符串长度为奇数,或者(s_1))或者(s_n)(时,才无解。

B. Red and Blue

因为(r)(b)中的元素时保留原数组中的顺序的。而且题目只关注前缀和的最大值,而根据前面的条件,原数组中的前缀必定是(r)的一段前缀和(b)的一段前缀中的元素组成。直接(O(nm))枚举一下,取最大值就好了。

C. Building a Fence

模拟。细节出锅,直接卡题自闭下分。

如果块在(i)处可放置的范围已经确定,那么块在(i+1)处可放置的范围也能求出来,而第一块的放置范围是已知的,所以可以从左到右依次放置,每次判断在当前范围内是否有满足要求的放置方法。

假设(i)处的可放置范围为([low, high])。其中(low)表示块的底部最低可以到多少,(high)表示块的顶部最高可以到多少。

因为块和前一个块至少有1单位的相交以及块不能插入地面,所以(low_{i + 1} = max(h_i, low_i + 1 - k))

因为块和前一个块至少有1单位的相交以及块不能离地超过(k - 1),所以(high_{i +1} = min(h_i + k - 1 + k, high - 1 + k))

然后对于(2 le i < n),有可行解的条件就是不能插入地面且不能离地过高,即要满足(h_i le high_i - k)(low_i <= h_i + k - 1)。对于最后一块,有可行解的条件是刚好在地表且不能插入地卖弄,即要满足(h_i le high_i - k)(low le h_i)

D. Ceil Divisions

第一个想法应该都是保留(2)(n)吧,然后最后再不断使用操作n 2,但是这种方法在(n)大的时候会超出次数限制。

但是保留(n)这个思路应该是没错的,接下来想到要找到另外一个数(r)保留,让(n)(r)操作,快速让(n)的变到(1),然后再用(2)(r)搞到(1)。然后就想到了用(r = lceil sqrt n ceil)。先将除了(1),(2)(r)以及(n)以外的数都与(n)操作,花费(n - 4)次操作。现在,两遍n r之后,出了(2)(r)以外都是(1)了。最后再用(2)去把(r)搞成(1)。这样(r)的上限大概是在(450)左右,好像差不多卡进去了。但是这个方法在(n = 2 imes 10^5)时会稍微超限几步。

然后,就想到了继续用这个方法取优化。大概就是再用一个(r^prime = lceil sqrt r ceil),在用(r)(n)搞到(1)之后,再用(r^prime)(r)搞到1,最后再用(2)(r^prime)搞到(1)。现在足够优秀了。

E. A Bit Similar

比赛的时候看错题了,然后就去看F了。事实上这题挺水的。

性质

一个(n)位二进制串(a),将其按位取反后得到串(b),串(b)和除了(a)之外的所有(n)位二进制串都至少有一个位相同。

解法

根据题意,最后的结果为一个(k)位二进制串,再结合前面的性质,可以推出则当(2^k ge 2e5)的时候,必定有解。特别的,当(2^x ge 2e5)时,最后结果的前(k - x)位都可以为0。

所以就可以枚举(x),至多枚举(max(n, log_2 k))次,就能找到结果或者得出无解的结论。

现在(x)就相当于常数了,然后前(k - x)位都是0,这个就可以匹配出一些串了。再枚举未匹配的串,把后(x)位标记一下。最后再枚举([0,2^x)),若这个解可行,就可以得到答案了。

F. Power Sockets

卡简单题+手速不够。

先放长的会比先放短的更优。

每次尽量对半,拿中间的点去和离根最近的白点连接。这样会比其他的方法更优。

每次加完后,离根第k近的白点深度可能会变化,那么就需要更新答案为两者中的较小值。

然后就是用一个线段树来模拟这个过程。大概就是用线段树(s_i)来记录深度为(i)的点的个数。每次就是单点减法(边的端点变黑),区间加法(新加入的白点)以及第一个满足(sum(0, i) ge k)(i)

前两个操作是线段树入门,最后一个是线段树上二分。

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