二分,三分,离散化,trie树,对顶堆
二分查找
特征
- 具有单调性的数组
- 求最大/最小值
- 答案离散(具有有限种可能)
做法
- 区间排好序
- 确定答案区间
- 在保证答案在区间内的前提下缩小区间
- 当区间缩小到仅包含一个解时,该解就是答案
两种写法
左闭右开区间
- 不直接找到目标值的写法,跳出循环后的num[l-1]要么是目标值,要么是目标值目标值左面的值;num[l]是目标值右面的值
1 | int l=0,r=n+1; |
- 直接找到目标值(适合写在函数里)
1 | int l=0,r=n+1;//右开,所以指向区间最右面的下一位 |
左闭右闭区间
- 和上面差不多(包括跳出循环的值),无非差别在于等于号以及r的区别
1 | int l=0,r=n;//右闭,所以指向区间最右面 |
三分
特征
类似于二分查找,三分搜索法也是比较常用的基于分治思想的高效查找方法。但是和二分不同,二分只适用于单调函数,三分用于单峰函数(求极值)
代码
1 | long double f(double x){// 算出某个点的函数值 |
离散化
使用场景
在数据规模较大(大于数组能开的范围),只需要数据的相对关系,而不需要数据的具体值时,我们可以使用离散化
代码
STL版
1 | for(int i=1;i<=n;i++) |
非STL版
1 | int a[MAX];// 源数据数组 |
Trie 树(字典前缀树)
例题传送门是他错误的点名开始了
介绍
Trie树是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
性质
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
- 每个节点的所有子节点包含的字符都不相同
功能模块
存储树
1 | struct Trie { |
建树
1 | void build(string s) { |
查询
1 | int query(string s) { |
对顶堆
介绍
可用于动态维护第k大的值(例如中位数),每次操作为O(logn)
例题P1168 中位数
我们需要分别维护两个堆,让小根堆的堆顶作为分界线,如果大于它就加入小根堆,否则就加入大根堆,如果两个堆的个数相差超过1,就将多的那个堆的堆顶弹出来放到另一个堆的堆顶。奇数个数的中位数显然是堆中数量最多的堆的堆顶。偶数个数的中位数则是两个堆堆顶取平均值。
加入元素的操作
1 | priority_queue<int> q_big;// 大顶堆 |