排序
快速排序
归并排序
二分搜索
整数二分
浮点数二分
高精度计算
数据存储
数组存大整数,并且小端存法——数组低位存放数据的低位。
加法
通常是两个大整数相加,各自的位数在 106 量级;
减法
通常是两个大整数相减,各自的位数在 106 量级;
乘法
通常是一个大整数乘一个稍小的数,大整数的位数在 106 量级,稍小数的数值在 106 量级;
除法
通常是一个大整数除以一个稍小的数,大整数的位数在 106 量级,稍小数的数值在 106 量级;
前缀和与差分
一维前缀和:
二维前缀和:
scanf 在输入较大的数(通常指 1,000,000 以上)时效率比 std::cin
更高,不过想要继续使用 std::cin
,则可以:
这段代码的作用是使 std::cin
变为异步操作,提高执行效率,副作用是不能再使用scanf
位运算
整数二进制表示的第 k 位的值
整数的最后一位 1
二进制中 1 的个数
还可以使用 lowbit()
来实现:
快速幂
双指针策略
常见问题分类:
- 对于一个序列,用两个指针维护一段区间
- 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
优势:将暴力方法中的逐项枚举,通过某种单调性质优化到 O(n)
利用两个数组的升序性质,通过双指针的方式来减少时间复杂度。具体做法是从数组 A 的头部和数组 B 的尾部开始进行查找,逐步向中间移动指针,直到找到满足条件的元素对。
离散化
此处特指整数的离散化。
通常整数可取的值域非常大,在 [0∼109] ,但是数组中元素数量却很少,如只有 104 个,那么为了高效地存储数据,需要将整数映射到 104 长度的数组中,这就是离散化。
区间合并
按区间左端点进行排序
题解:
- 按行进行区间合并
- 按列进行区间合并
- 判断行列的重叠部分减去多加的
存储结构:
对于行和列要存储三个值,分别为区间左右或上下端点以及一个标识表示那一行或那一列!
- 行或列的标识:当然是行或列相同的哪一个数字
- 左右端点:当然是不相同的一组中较小值和较大值
对于排序:
- 可以重载小于号,也可以直接在外面写一个
cmp
函数传入 sort
进行比较!
- 优先按照行或列的标号从下到大,然后就是按照左端点和右端点!
区间合并:
- 保证在同一行
k == seg.k
- 区间无法合并
ed < seg.l
,则进行上一个区间的保存,同时更新左右端点
- 可以合并,则进行合并,更新右端点
- 不在同一行,直接将上一个区间保存,同时更新新的区间的左右端点以及行或列的标识
k
- 记得最后一个区间的保存,for 循环无法处理最后一个区间的保存
- 最后将保存的容器还原到原始的 segs,通过引用传回去!
- 注意: 对于每次合并当然都得判断起始点是否是-2e9
计数:
每次保存就是一个新区间,将区间长度累加一下即可,cnt += ed - st + 1
去重:
即只要是横着的和竖着的有相交就去减掉一个重合点,判断条件 (画个图就知道了):
row.k >= col.l && row.k <= col.r && row.r >= col.k && row.l <= col.k
时间复杂度:
- 区间合并:O(n)
- 快排:O(nlogn)
- 去重:O(n2)
代码: