二分
-
二分查找
通常使用(STL)的(lower\_bound)和(upper\_bound)实现(自己写容易出错)
-
二分答案
整数域上的二分
while(l <= r) {
int mid = (l+r)>>1;
if(chk(mid)) ans = mid,l = mid+1;//ans的位置视情况而定
else r = mid-1;//注意else 经常会忘写
}
实数域上的二分
- 实数二分尤其应注意精度问题,通常(eps)(误差值)要设为要求精度的要求位数的后两位(如要求(10^{-6}),(eps)要设为(10^{-8}))
while(l < r-eps) {
double mid = (l+r)/2;//注意非整数不能使用>>运算
if(chk(mid)) l = mid;
else r = mid;
}
- 有时也可采用固定循环次数来控制精度
for(int i = 1;i <= 100; ++i) {
double mid = (l+r)/2;
if(chk(mid)) l = mid;
else r = mid;
}
离散化
-
离散化是一种数据处理的常用技巧,相当于一种(hash),实质是一种映射关系
-
通常要为要离散的数组(可能是一堆元素的某一种属性)建立一个辅助数组(\_a[N]),记录原数组的值,将辅助数组排序,去重,在(\_a[N])中查询原数的序号即为原数新的权值
sort(_a+1,_a+n+1);
int cnt = unique(_a+1,_a+n+1)-_a-1;//注意要-1
for(int i = 1;i <= n; ++i) {
a[i] = lower_bound(_a+1,_a+cnt+1)-_a;
}
-
区间离散化
区间离散化通常要另加节点(为防止原来不连续的变得连续,可参考P3740 [HAOI2014]贴海报)