前言
D 题看起来就像是二分,但不知道怎么写 check ,而且二分不熟……每次写二分的时候都担惊受怕。干脆花了一晚上总结了一下各种二分的写法。以后写二分应该没有那么慌了。
二分的总结明天或后天再写吧。留个坑在这里。
限时只做了 A、B、C 三题,D 题后面补了。 E、F 题估计是不补了。以后有机会再康康吧。
题解
A. Deadline
题目大意
给定 (n, d) 判断是否存在一个整数 (x) 使得 (x + lceildfrac{d}{x + 1} ceil le n)
分析
一波数学推导有:
当且仅当 ((x + 1)^2 = d) 也就是 (x = sqrt d - 1) 的时候取得最小值。
直接算出 (x) 和 (x + 1) 时 (x + lceildfrac{d}{x + 1}
ceil) 的值,代入与 (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) ,那么有:
枚举算一下在小于 (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) 的方法数,那么显然有:
边界为:
对于 (b) 数组类似,有
边界为:
所以,对于确定的 (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) 后,再重复一次上面的操作就能得到是哪两个数组了。