高精度除以低精度
// A / b = C ... r, A >= 0, b > 0 表示A除以b的商是C,余数是r,A是非负整数,b是正整数
vector<int> div(vector<int> &A, int b, int &r)
{
vector<int> C; // 创建一个空向量C,用于存储最终的商
r = 0; // 初始化余数r为0
for (int i = A.size() - 1; i >= 0; i--) // 从A的最低位开始遍历,即从A.size() - 1开始递减
{
r = r * 10 + A[i]; // 将当前余数r乘以10,然后加上A当前位的值,构建出被除数的当前值
C.push_back(r / b); // 将构建出的被除数除以b得到的商压入C中
r %= b; // 更新余数r为被除数除以b的余数
}
reverse(C.begin(), C.end()); // 因为C是从最低位开始构建的,所以最后需要反转C,使其成为正常的正序
// 移除C末尾的0,直到遇到非0或者C只有一个元素
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C; // 返回最终的商C
}
双指针算法
for (int i = 0, j = 0; i < n; i++) // 初始化两个循环变量i和j,从0开始。循环条件是i小于n,每次循环i自增1
{
// 内部while循环,用于调整j的值
while (j < i && check(i, j)) // 当j小于i并且check(i, j)为真时,继续循环
{
j++; // 根据check函数的逻辑,增加j的值
}
// 具体问题的逻辑将在这里实现
// 这里没有给出具体的逻辑,因此无法提供详细的注释
// 通常这里会根据i和j的值执行一些操作,例如计算、比较或更新某些数据
}
常见问题分类:
(1) 对于一个序列,用两个指针维护一段区间
(2) 对于两个序列,维护某种次序,比如归并排序中合并两个有序序列的操作
离散化
vector<int> alls; // 定义一个整数向量alls,用于存储所有待离散化的值
sort(alls.begin(), alls.end()); // 使用标准库函数sort对alls中的值进行升序排序
alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 调用unique函数从alls中移除重复的元素,erase函数用于实际删除unique函数标记的重复元素之后的所有元素
// 二分查找算法,用于求出x对应的离散化的值
int find(int x) // 函数find接收一个整数x作为参数,返回第一个大于等于x的位置
{
int l = 0, r = alls.size() - 1; // 初始化左右指针l和r,分别指向alls的起始和结束位置
while (l < r) // 当左指针小于右指针时,继续循环
{
int mid = l + r >> 1; // 计算中间位置的索引mid,使用无符号右移来实现除以2的操作
if (alls[mid] >= x) r = mid; // 如果mid位置的值大于等于x,则将右指针r更新为mid,因为第一个大于等于x的值在[l, mid]区间内
else l = mid + 1; // 否则,将左指针l更新为mid + 1,因为第一个大于等于x的值在[mid + 1, r]区间内
}
return r + 1; // 当循环结束时,l等于r,此时l指向第一个大于等于x的值,返回l + 1将其映射到1, 2, ..., n的序列
}
区间合并
// 将所有存在交集的区间合并
void merge(vector<PII> &segs) // 定义函数merge,接收一个二维整数向量segs的引用,其中PII是一对整数的缩写,表示区间的起始点和终止点
{
vector<PII> res; // 创建一个向量res,用于存储合并后的区间
sort(segs.begin(), segs.end()); // 对输入的区间向量segs进行排序,使得区间按照起始点从小到大排列
int st = -2e9, ed = -2e9; // 初始化两个变量st和ed,分别代表当前合并区间的起始点和终止点,初始值设为-2e9,一个不可能的区间起始值
for (auto seg : segs) // 遍历排序后的区间向量segs
if (ed < seg.first) // 如果当前区间seg的起始点大于之前区间的终止点ed,说明没有交集
{
if (st != -2e9) res.push_back({st, ed}); // 如果当前合并区间st和ed已经确定,将其添加到结果向量res中
st = seg.first, ed = seg.second; // 更新当前合并区间的起始点和终止点为当前区间seg的起始点和终止点
}
else ed = max(ed, seg.second); // 如果有交集,即当前区间的起始点小于等于终止点ed,则更新终止点ed为当前区间和上一个区间终止点的最大值
if (st != -2e9) res.push_back({st, ed}); // 如果最终合并区间st和ed已经确定,将其添加到结果向量res中
segs = res; // 将合并后的区间向量res赋值给输入向量segs
}