①双指针算法
一般做题:先用暴力做法,然后去看是否存在某种性质(如单调性,维护这个区间的单调性即可)
AcWing 799. 最长连续不重复子序列 - AcWing
核心:其中一个指针不会回退!
②位运算
i)求n的第k位数字: n >> k & 1
ii)返回n的最后一位1:lowbit(n) = n & -n(利用i可以用for循环直接求出一个数字的二进制表示
对于ii,-n实际上就是取n的补码+1)
AcWing 801. 二进制中1的个数 - AcWing--->lowbit的应用
③离散化
vector<int> alls; // 存储所有待离散化的值 sort(alls.begin(), alls.end()); // 将所有值排序 alls.erase(unique(alls.begin(), alls.end()), alls.end()); // 去掉重复元素 // 二分求出x对应的离散化的值 int find(int x) // 找到第一个大于等于x的位置 { int l = 0, r = alls.size() - 1; while (l < r) { int mid = l + r >> 1; if (alls[mid] >= x) r = mid; else l = mid + 1; } return r + 1; // 映射到1, 2, ...n }
④区间合并
// 将所有存在交集的区间合并 void merge(vector<PII> &segs) { vector<PII> res; sort(segs.begin(), segs.end()); int st = -2e9, ed = -2e9; for (auto seg : segs) if (ed < seg.first) { if (st != -2e9) res.push_back({st, ed});//不要将-inf加入答案 st = seg.first, ed = seg.second; } else ed = max(ed, seg.second);//更新区间 if (st != -2e9) res.push_back({st, ed});//将最后一次的区间加入(同时也防止为n=0) segs = res; }
细节:res的两次push_back