算法理解
二分用于解决答案具有单调性问题(经典最大值最小问题),是一个好的入手点,用一个log的复杂度,将求解答案转化成了判断答案是否合法
实数域上的二分
两种方法:确定精度eps,固定枚举次数,一般后者精度大于前者
T1:
二分最大值,注:如果有一个数本身就大于二分答案,则答案肯定错误,证明:考虑如果只有一个数大于二分答案,其余都正常,可能就会小于分段数,导致答案错误
T2:(T_T)
单纯枚举位置判断这个位置上防具奇偶是不具有单调性的,考虑只有一个位置为奇或全为偶,如何想到的呢:我们先判断是这两种情况的哪一种,显然,如果全部防具加起来为偶,则全为偶,反之则有一鸡,我们可以将这个结论推广,在二分的位置x时,若0~x中有总防具为鸡,则防具个数为鸡的位置必然在前面,反之则在后面,具有单调性
T3:(T_T)
实数内二分平均数,判定是否存在一个长度不小于L的数列,平均数不小于mid,存在性问题,找极端值,就是找平均数最大的序列,平均数是用段的和除以元素个数,我们想只统计段的和,所以,考虑将每一个数都减去平均数,现在问题就转化成了维护一段长度不小于L的和的最大值,考虑统计前缀和,问题又变成了找到对于一个右端点为i的区间,找到一个0~i-L中的最小前缀和,它们相减就是这段的和,找到最大的和,判断它是否大于等于0,是,则存在这样一个序列,具有单调性
T4:
二分选多少宠物,n<50,乱搞即可
T5:
同上题,找到前m大的数,但复杂度太高了,瓶颈在sort排序,考虑将排序优化到O(n),用一种新奇的STL:
std::nth_element(a+1,a+m,a+n+1,cmp);
用法详见OI viki
注:a+m指的是a[m]