- 多组用例还是一组, EOF
- 倍增表构建边界 st[i][p] = std::max(st[i][p-1], st[i+pows[p-1]][p-1]); 注意三个p-1 查询时注意+1:std::max(st[L][p], st[R-pows[p]+1][p]);
- 注意二维数组维数含义弄反f[MAXN]
- 前向星链表中,注意head和edges大小不要弄反
- 倍增表注意下表开始是从0还是1. 普通倍增是从左闭又开。 树上倍增是f[i][0]是i的father
- lca最近公共祖先:暴力标记;树上倍增(x,y先移动到同一高度,再一起向上走,ans=d[a]+d[b]-2*d[lca]; 欧拉遍历序列中第一次出现a,b位置中的最小deep是lca+倍增求最小; 离线tarjan+并查集
- 并查集:路径压缩, 带树并查集(食物链,模3加法);扩展并查集,a和a的影子,表示不在一个集合,被放到同一个集合中在同一范围的是同一个类,不是同一个范围(a,a的影子)则不是同一类
- 二维倍增表,其实就是每行一个倍增表,多行遍历即可求矩阵内的最大最小
- 倍增表最大最小最连续最频繁
- 优先队列:第k大,第k小,最大k个,最小k个, 大用小顶堆,小用大顶堆。 哈夫曼树;单调队列优化动态规划为贪心(加油漏油到终点问题)
- 并查集 带权 注意左开右闭(实际上是计算树的边,而不是node) 如果fx = fa[x]; fa[x] = find(fa[x]) d[x] += d[fx]
- 树状数据注意从下标1开始,ADD: i + lowbit(i); Query: i - lowbit(i) lowbit: i & -i; i & (~i+1);
- 累加注意溢出,统一用long long吧。
- 线段树区间和,区间上累加v, sum += (r-l+1)*v, push_down也要注意
- 线段树query/update时runtime_error注意mid=(tree.l + tree.r) / 2; 注意不要写成要查询区间[a,b]的(a+b)/2. 最好代码里把树里的结点叫l,r.查询区间叫a,b,否则空间弄混了
- 线段对注意要开辟4倍空间,小心越界
- 线段树对输入的查询区间a,b, 注意看清题目会不会保证a<=b;
- 线段树update/query时可以简单:l,r,a,b, a<=l&& b>=r时表示覆盖了这个区间。 m=(l+r)/2; if(a<=m) qu(2*k, l, r, c); if(b>m) qu(2*k+1, l, r, c); 一直划分变小l,r直到[a,b]覆盖[l,r],这样就不用分类分的太细如b<=mid; a>mid; ([a,mid], [mid,r])
- long long要用%lld读取,否则出问题
- 分块很粗糙bsize=sqrt(n),直接 L=a/bsize, R=b/bsize; 分为 左不全L,右不全R和中间[L+1,R-1],即使L是全的也不用考虑,暴力即可
- 分块的lazy 求sum不需要push_down. sum和lazy同步更新
- 分块当a,b处于同一块时直接暴力,小心处理两遍
- 分块下标从0开始比较直观,注意输入的是1到n.要减一
- 注意在使用多个数组时,可能最关键的数组大小没问题,其他数组由于大小没设置好导致越界runtime error,trie树时的end数组
- 字典树判断前缀注意,长的包含短的前缀,要判断end. 短的是长的前缀,要看是不是所有经过结点都已经存在。
- trie树在多组输入数据时,记得每次要清0.
- 全局变量在多组输入数组时,每次要清0. 记得一个个全局变量看,每个是否要清0
刷题哇(WA)哇哇到吐?看这篇防哇(WA)指南,立即AC
于 2024-01-30 22:22:34 首次发布