CF888E
今天听了钟皓曦大神的讲解,扫了一眼题解区,大家都是在论述折半搜索 但是对于排完序之后的数组,进行互相匹配的时候,几乎说的都不是太透彻(个人观点,随便来喷)
于是我决定写一篇较为详细且严谨的题解
考虑当前有一个p属于对于前一半进行dfs得到的数组里面的一个数字,
考虑当前有一个q属于对于后一半进行dfs得到的数组里面的一个数字,
显然,我们知道:\(p<m,q<m\),因此可以推出\(p+q<2\times m\)
我们也知道我们的答案是\((p+q)\;mod\;m\),因此需要来讨论\(p+q\)的大小对m造成的影响
第一种情况:
- \(m<p+q<2\times m\)
- 此时显然\(p+q\)往大里取最好,因为取的值越大,在\(mod\;m\)之后所得到的结果越大
第二种情况:
- \(p+q<m\)
- \(O(n^2)\)匹配来找答案,显然不优,此时需要搞一个双指针来优化
1 | sort(sum1 + 1, sum1 + cnt1 + 1), sort(sum2 + 1, sum2 + cnt2 + 1); |
将两个数组排序,初始化的时候l指向sum1数组的末尾(最大值),r指向sum2数组的开头(最小值)
考虑对于sum2数组中的每一个数字,在sum1中找到某一个数字,使得两者加起来在小于m的情况下最大
具体实现见代码。
此外,给出证明:由于sum1与sum2数组是递增序列,所以一遍扫过来,找到的一定是最优解
如果\(sum1[l] + sum2[r]>m\),显然,\(sum1[l] +sum2[r+1]\)也一定是大于m的,l递减显然没有问题
代码给出:
1 |
|