大神们总结的二分的两种经典模板
1.
while (l < r)
{
int mid = l + r >> 1; //(l+r)/2
if (check(mid)) r = mid; // check()判断mid是否满足性质
else l = mid + 1;
}
2.
while (l < r)
{
int mid = l + r + 1 >> 1; //(l+r+1)/2
if (check(mid)) l = mid;
else r = mid - 1;
}
这两者的区别是,一个向左找答案,一个向右找答案平时在运用的时候,要先将问题要找的答案区间弄清,这样就可以套公式了。
二分的应用分为二分查找和二分答案,两者的区别是,二分查找有一个确定要找的值,不断缩小搜索范围,而二份答案只有一个答案区间,不断缩小答案区间范围求出最优解。
一般题目中说找某个值,利用二分查找,而找最小值的最大,最大值的最小这类的描述,就是要用二份答案。
并查集
并查集是一种数据结构,主要作用就是用来判断联通关系(两个事物之间是否有某种关联)。
并查集主要由一个整型数组pre[ ]和两个函数find( )、join( )构成。
数组 pre[ ] 记录了每个点的前驱节点是谁,函数 find(x) 用于查找指定节点 x 属于哪个集合,函数 join(x,y) 用于合并两个节点 x 和 y 。
find函数模板
int find(int x)
{
while(pre[x] != x)
x = pre[x];
return x;
}
join函数模板
void join(int x,int y)
{
int fx=find(x), fy=find(y);
if(fx != fy)
pre[fx]=fy;
}
我在写并查集类型的题一般的结题过程:
1.判断元素范围。
2.从一队元素开始,判断联通性(比较两个元素的“祖先”)。(题目中若有需要,符合条件的合并)
3.判断是否联通,或者统计独立联通块的个数。(一般答案就是这些)
照例贴一下相关链接: