Educational Codeforces Round 80 (Rated for Div. 2)

前言

D 题看起来就像是二分,但不知道怎么写 check ,而且二分不熟……每次写二分的时候都担惊受怕。干脆花了一晚上总结了一下各种二分的写法。以后写二分应该没有那么慌了。
二分的总结明天或后天再写吧。留个坑在这里。

限时只做了 A、B、C 三题,D 题后面补了。 E、F 题估计是不补了。以后有机会再康康吧。

比赛链接


题解

A. Deadline

题目大意

给定 \(n, d\) 判断是否存在一个整数 \(x\) 使得 \(x + \lceil\dfrac{d}{x + 1}\rceil \le n\)

分析

一波数学推导有:

\[x + \lceil\dfrac{d}{x + 1}\rceil = x + 1 + \lfloor\dfrac{d}{x + 1}\rfloor = \lfloor x + 1 +\dfrac{d}{x + 1}\rfloor \ge \lfloor2\sqrt{d}\rfloor \]

当且仅当 \((x + 1)^2 = d\) 也就是 \(x = \sqrt d - 1\) 的时候取得最小值。
直接算出 \(x\)\(x + 1\)\(x + \lceil\dfrac{d}{x + 1}\rceil\) 的值,代入与 \(n\) 判断即可。

代码

B. Yet Another Meme Problem

题目大意

给定 \(A, B\) 找出所有的二元组 \(1 \le a \le A\)\(1 \le b \le B\) 使得\(a \cdot b + a + b = conc(a, b)\),其中 \(conc(a, b)\) 是将 \(a, b\) 直接相连起来。例如 \(conc(12, 23) = 1223\)\(conc(100, 11) = 10011\)

分析

不妨设 b 的位数为 \(n\) ,那么有:

\[ab + a + b = 10^n\cdot a + b \Rightarrow b = 10^n - 1 \]

枚举算一下在小于 \(B\) 时有多少个 \(b\) 满足 \(10^n - 1\) 算出 \(n\) 。再乘以 \(A\) 即可。

代码

C. Two Arrays

题目大意

给定数组长度 \(m\) ,和数字范围 \([1,n]\) 构造两个数组,使得 \(a\) 数组不降,\(b\) 数组不升。且对于两个数组每个元素,都有 \(a_i \le b_i\) 。询问有多少种构造方法?

分析

\(a\) 数组不降,\(b\) 数组不升,且 \(a_i \le b_i\) ,那么 \(a_{max} \le b_{min}\) ,所以我们不妨枚举 \(b_{min}\)

\(dp_1[t][m]\)\(a\) 数组中,第 \(m\) 个空填数字 \(t\) 的方法数,那么显然有:

\[dp_1[t][m] = \sum_{i = 1}^tdp_1[i][m - 1] \]

边界为:

\[dp_1[t][1] = 1 \]

对于 \(b\) 数组类似,有

\[dp_2[t][m] = \sum_{i = t}^ndp_2[i][m - 1] \]

边界为:

\[dp_2[t][1] = 1 \]

所以,对于确定的 \(b_{min}\) 的总的构造方法数为 \(dp_2[b_{min}][m] \cdot \sum_{i = 1}^{b_{min}}dp_1[i][m]\)。用记忆化优化总的时间复杂度为 \(O(n^2)\)

听说这题还能用组合数学直接得出公式,留坑待填。

代码

D. Minimax Problem

题目大意

给定 \(n\) 个数组,每个数组长度为 \(m\) ,要找到其中的两个数组 \(a, b\) ,构成一个新的数组 \(c\) , 其中 \(c_i = \max(a_i, b_i)\) ,使得数组 \(c\) 的最小值最大。

分析

最大化最小值,一看就很有二分的味道。然而我想了半个小时没想出来。无奈只能求助 wj 。wj 很快就给出了一个二分的解法(wjnb!!)。具体思路是这样的:

假设我们找到的最大的最小值为 \(x\) 那么对于每个数组的每个元素,我们把大于等于 \(x\) 的值变成 \(1\) ,小于的变成 \(0\) 这样就构成了一个二进制串。然后留意到 \(m\) 最大只有 \(8\) 那么可以状压一下,开个数组记录一下这个序列出现过。

然后对于每个数组的二进制串,我们只要找到另外一个二进制串( \(m\) 只有 \(8\) 直接枚举长度为 \(m\) 的所有串,再用数组判断有没有出现过即可),使得这两个串位或起来全为 1 即可。

在二分找到最大的最小值 \(x\) 后,再重复一次上面的操作就能得到是哪两个数组了。

代码

posted @ 2020-01-17 01:39  ljxtt  阅读(289)  评论(0编辑  收藏  举报